UIViewController not passing touches to other Views - objective-c

I have an overlay view (covering the entire screen), I can receive touches but it isn't passing them down the responder chain.
I add the subview like this:
UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow insertSubview:self.view aboveSubview:mainWindow];
It doesn't seem to matter if I use addSubview or insertSubview.
My touchesBegan looks like:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//do some stuff here..
[super touchesBegan:touches withEvent:event];
}
It doesn't seem to matter if I am using SUPER or various other combinations of self.nextResponder, etc..
In the end, I need to have an overlay view that covers the entire screen, I need to detect touches then pass them to the views/viewControllers below them.
Thanks!

You are addView to the mainWindow, your super view is the mainWindow, not the viewBlow it.
You need to add the view to VC's view, and if you want the full screen. set the status bar to hidden (or transparent. not tried) and then set the view's frame to (0, -20, weight, height+20).

Related

Interactive touch display

I'm looking to intercept all touch events on a parent UIView and display where the user touches but still bubble those touch events to children views i.e.. UIButtons, UITableViewCell, etc. so those children interact via their default manner.
I have no issues displaying touch events interactively on UIView using basic delegate methods:
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
}
My issue at this point is bubbling these events to next responder when UIView contains other interactive children views such as UIButtons. touchesBegan: is never fired on parent view when tapping a button so I'm not able to display something "pretty" to user when taps buttons.
Is there a better way other than creating category for UIButton, UITableViewCell? Thanks
Here is an example of what I'm looking to do anytime user touches the screen... (notice the white circle when user touches buttons):
https://m1.behance.net/rendition/modules/154366385/disp/9532a948c71e28ffda2219600c05ffd9.gif
You can do it by creating a subclass of UIView.
The view should be on the top of the view hierarchy and its size should be full of the screen.
All touch events will be sent to this view. If you return NO in the pointInside:widthEvent: method, the touch event will be sent to the lower objects.
#implementation MyView
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
// show bubble here
return NO; // send touch events to lower layer objects.
}

How do I forward touch events to a view behind a uicollectionview?

I have a uicollectionviewcontroller which I use to create a small toolbar at the bottom of the screen. I add the view of the uicollectionviewcontroller to another viewcontroller's view. My problem is that it won't forward touch events to a view underneath it. I did move it to the bottom and that worked for a while but now I need to use 2 uicollection views.
How am I supposed to forward touch events to views beneath a uicollectionviewcontroller's view?
In case the question is still relevant, the following can be used to achieve touch forwarding.
Subclass UICollectionView
Overwrite - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[super touchesEnded:touches withEvent:event];
[self.yourCustomDelegate forwardTouches:touches withEvent:(UIEvent *)event];
}
That is how UICollectionView can keep its ability to respond to user interaction, and the same time forward received touches.
As i think you can add your toolbar as footer of UICollectionView and it will work
have a look into this link How to Add Header and Footer View in UICollectionView

Transparent UIView on top detecting touches

I have an iPad project structured with a UISplitViewController:
RootViewController
DetailviewController
Both of them are detecting touches with Gesture Recognizer inside their own Class.
I would like to create a transparent UIView on top of all the Classes to detect ONLY a Diagonal Swipe (from the left bottom corner to the right top corner).
So, when the swipe will be detected I will launch a function otherwise nothing appended and the touch should be passed on the low level view.
I tried these two solutions:
Add a GestureRecognizer on this top transparent view but this will hide all touches to the lower hierarchy views.( with userInteraction enabled: YES ofcourse);
The other solution is to make the init like this
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setBackgroundColor:[UIColor colorWithWhite:1 alpha:0.01]];
[self setUserInteractionEnabled:NO];
}
return self;
}
and try to detect the swipe with
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
But at this point all the touches are not detected.
Anybody have a nice solution?
I will not create a transparent UIView like you are mentioning. I will add a UISwipeGestureRecognizer to the UISplitViewController's view this is already the view that contains all your subviews. You can have access to the view within the app delegate:
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
// attach the swipe gesture to the view that embeds the rootView and the detailView
UISwipeGestureRecognizer* swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:splitViewController.view action:#selector(swipeUpdated:)];
Can't you just add a gesture recognizer to the UISplitViewController's view?
You should look into Container Controllers. You can make your own SplitViewController and make a third view on top of the controller that detects the swipe. Custom container controllers are pretty straight forward and gives you a lot of flexibility.

Adding touch-area to UIView (iOS5)

I have a MainView with MainViewController. Now I want to add a specific area where I want to register touches (painting in a specific area). How could I do this?
I thought about adding a sub-view with its own sub-viewcontroller, but this guy tells this is not a good approach.
The post you linked to is partially out of date because it was written before Apple introduced support for View Controller Containment in iOS 5.
That said, it's your choice whether:
the subview is managed by its own view controller or
you use the MainViewController directly to respond to touches in the subview or
you create a UIView subclass that interprets touches on itself without the help of a view controller.
Add a custom view as a property, called touchArea
-(void) touchesBegan/Moved/Ended (NSSet *)touches withEvent:(UIEvent *)event {
CGPoint location = [[touches anyObject] locationInView:self.view];
if (CGRectContainsPoint(touchArea.frame, location))
//code
}
}

UIScrollView decide between drag and tap

I am trying to determine a Single Tab on a View inside of a UIScrollView. The Problem is that The UIScrollview catches all the gestures.
What I tried so far:
I override the following method in my UIScrollView:
-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
UITouch *touch = [touches anyObject];
if([touch tapCount]== 2) return YES;
return NO;
}
This works fine, I can now reach the UITapGestureRecognize on my UIView, unfortunately I can only detect double-taps because the [touch tapCount] == 1 is always beeing called (dragging or zooming in the UIScrollView). But actually the UIScrollview does not need the "Single-Tap-Function"
Is there a way to decide between a drag (Scroll or zoom) and a single Tap inside this method? I cant find it..
-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
Thanks in advance
Fabi
It sounds like you only want the tap recognizer to succeed if the touch doesn't scroll the scroll view. This is pretty easy because the scroll view uses a pan gesture recognizer for scrolling. On iOS 5, you can just do this:
[self.tapRecognizer requireGestureRecognizerToFail:self.scrollView.panGestureRecognizer];
If you want to support older versions of iOS, you have to do this:
for (UIGestureRecognizer *recognizer in self.scrollView.gestureRecognizers) {
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]])
[self.tapRecognizer requireGestureRecognizerToFail:recognizer];
touchesShouldBegin: is a delegate method on UIView. It is not part of a UIGestureRecognizer.
You'll need to create a UITapGestureRecognizer, set the number of taps you want to trigger the recognizer and add it to your view.
Here is the documentation for UITapGestureRecognizer
I'm assuming you meant "single tap"--your scrollView belongs to the UIView tied to your controller. Assign the tap gesture recognizer to the that UIView. It gets first picks on all gestures and then passes down the ones it isn't interested in.