Make UIControl only accept swipe gestures and pass along touch/tap gestures - ios

I'm developing an iOS 8.1 app for an iPhone 5 in Objective-C using Xcode 6.1.
When a UITextView is clicked, I have an invisible UIControl view that pops up just above the keyboard, so that the user can swipe down from above the keyboard and dismiss the keyboard (and then move the UIControl out of view again). This is working fine. However, this UIControl view that pops up above the keyboard is covering another UITextView such that the covered text view cannot be tapped on. Every time I try to tap on the covered text view (which is visible because the UIControl is not opaque), nothing happens because the UIControl seems to just be taking the taps and not doing anything with them.
My question is, how do I make it so that the UIControl simply ignores taps (letting them go straight through so that the UITextView underneath can accept them), and yet accepts swipes (so that, when it is swiped downward, it can dismiss the keyboard and move out of view)?
I've tried several solutions but haven't found one that will work well for what I want.
Thanks!

This question is similar to yours. Subclass your UIControl and override - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event and call its super variant to pass it up to its view.

There is another way to do this. Change the main view of your UIViewController to a subclass of UIControl instead of UIView. Connect the following IBAction to the view in order to dismiss the keyboard when the background is tapped.
- (IBAction)backgroundTapped{
[self.view endEditing:YES];
}
Apple Documentation - endEditing:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
Use this event. If tap gesture return no.

Related

Disable userinteraction or touches event in UIView but still enable for subview

I have UIView like this.
I need to put my finger on that view and drag along on those button just like playing piano. Problem is that if initial touch point is on the main view and if I drag along, touches event for main view is triggered and my buttons touch events are not triggered.
As a result, I put this.
[self setUserInteractionEnabled:NO];
Problem is that it has disabled my buttons and other subviews. I want to totally ignore touch event, user interaction from main view but allow for all those subview. How shall I do?
You can set up a notification event for keyboardWillShow and inside the target function set [self setUserInteractionEnabled:NO]; for the superView and when keyboardWillHide notification re-enable it. For hiding the keyboard you could use the GO Button or to dismiss the keyboard add an invisible UIButton to the remaining part of the Screen when the keyboardWillShow event is called and use it to resign first responder.
Hope this helps.
You should create a subclass of UIView for your main view. It should overwrite - hitTest:withEvent: returning always the nearest view for a key.
An alternative solution without inheritance is giving all keys an invisible border such that their views cover the complete main view but never returning the main view.

UIButton not responding to touches - no scroll view

This is my view hierarchy. Send arrow is not responding immediately on the device, it takes multiple touches to trigger the action. But on the simulator, it works perfectly fine. There are no explicit gesture recognisers added in any view, no scroll views and the super view does not delay touch events or anything that I'e noticed in similar questions.
EDIT: Action added through the storyboard. I tried for all touch events and for all of them, the touch is non responsive. Only after a few touches, the action is triggered.
Here's the view debug hierarchy.
Is there any reason why the touch trigger is blocked here? I'm stymied. Help?!
Google Maps override the touches of Views.
Use this way to add your Views.
[self.view insertSubview:viewToAdd aboveSubview:mapView_];
If You adding Views for XIB then Send you map view to back.
[mapView_ sendSubviewToBack:YourView];

UIScrollView - Move keyboard with touch drag like iOS 7 mail app?

I'm curious how iOS 7 mail app is moving and dismissing the keyboard according to user's touch drag on new message screen.
Also it's implemented on comments screen of instagram app.
Can it be implemented through public apis?
UIScrollView has a property called keyboardDismissMode that allows you to set different behaviours. I think this is what you want:
scrollview.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
In your view controller just using [self.view endEditing:YES]; when the user taps on the view.
For the drag animation you have to use CoreAnimation and gesture recognizer based on keyboard frame.

How to detect touch on screen in custom UIView?

I want to watch in my UIView subclass for user touches on the screen. Especially there are some additional conditions:
the touch should not be catch by my view (for example, if user taps some button or scrolls something that action should be accepted)
there can be multiple views which are watching for touch and they should not conflict with each other
the approach should be as general as possible (so we can catch taps on tabbar or navigation buttons)
I can suppose to add specific fullscreen view with customized hitTest: method. This view has interface to add/remove delegates for watching for touches. But this method is "hard" in coding terms and I would like to find more elegant and simpler solution.
you can write touchesBegan in that UIView subclass.
Because if it had any subview like button or scrollView, they would be first responders ,and touches on scrollView wont fire touchesBegan of your UIView subclass.
And it wont conflict with other touch listeners unless the listener subView is explicitly passing that touch to your Subclass.

Generic way to detect a touch outside UIView frame

I have UIViewController with a custom UIView inside (lets call them VC and button). When button is touched, it's bounds and center changes with animation (it becomes bigger and presents a few options to choose from, after choice it resizes back). I would like to know how to "detect" (and dismiss the default action of that touch) a touch outside of the button (just to "hide" the button, in particular to make button resize to default smaller size).
Is there any generic way I could do that? VC has a lot of objects inside its view (table views, buttons, text fields, custom charts made with quartzcore, etc), do i need to block "interactivity" on all of those elements during the "big mode" of button?
You could subclass what ever view you are using and expand the coordinates that will correspond to a touch in the view by implementing
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
Read more in the docs
http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/hitTest:withEvent:
This way of implementing it is suggested in some WWDC videos from last year
Add a UIButton having the frame CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height) as the first subview to your mainview (self.view) , add a selector to this button (#selector(backgroundTap)) , now add all other subviews like UITableView , UIButton , etc (as per your requirment) . Now whenever you will click on to the blank space where no Subview is present the backgroundTap selector will be called.

Resources