iPhone Input with Stacked Views - iphone

I've got a situation in an iphone application where buttons are not receiving input as I expect. Here's the setup:
ViewMain - The main view full of various images and labels
ViewOverlay - A HUD like overlay view with two UIButton objects.
To create my scene I do the following:
viewController.view = ViewMain
[ViewMain addsubview:ViewOverlay]
This view renders as expected, with ViewOverlay correctly rendered ontop of ViewMain. However the two buttons found inside ViewOverlay do not receive touch events and can not be pressed. Tapping them does nothing at all.
I very well may be going about this in the entirely wrong direction. Any ideas?

1) Check that you've connected buttons' touch events (with Interface Builder or programmatically - something like Touch Up or Touch Down).
2) Check that all your parent views (for buttons) can get user touches (User Interactions Enabled == YES to all parent views) - if some parent view can't receive touches, responder chain for it's subviews won't be checked.

Related

Avoiding touch gesture conflicts between two different views

Let me emphasize that there are two views that overlap and I want handle the touch gestures of the view on top.
The UIGestureRecognizeDelegate methods work for conflicting gestures within one view not two views from what I have read. Please don't link me to those threads without explaining.
This issue is occurring between the toolbar items and an image view with gestures attached to it.
In the image above the bar buttons cannot be touched.
Other apps handle this case without issues. If I touch a bar button it would work and if I drag the view on the non-overlapped parts I would be able to drag it.
How can I achieve this ?
Currently the image view has gestures attached to it (one for testing, its a pan).
Update
As requested here is a Gif.
Notice how the buttons are not responding when there is a view under the toolbar.
The issue was that I was using view.layer.zPosition, apparently changing the zPosition does not change the position of view is the subview hierarchy (which was something that I assumed).
Source: https://stackoverflow.com/a/15807250/3366784

Disable all superviews except a specific view

I have UIView that open with a UIButton click. I want to disable user interaction of all other superviews except to this specific view and his subviews, how can I do that? Just to make this view the only view that will response to user touch.
Thanks!
Agree with the comment, you probably want to disable all siblings of a view... (edited so you can set them back to enabled at some point)
- (void)setSiblings:(UIView *)view enabled:(BOOL)enabled {
for (UIView *sibling in view.superview.subviews) {
if (sibling != view) sibling.userInteractionEnabled = enabled;
}
}
I know you already accepted an answer but a better (and easier) approach is to display the new view full screen. Make the new view with a clear background. Then add the real view as a subview to this full screen view. This way you don't have to mess with any existing views to display this new view. You can still see everything behind it but touch events are blocked by the clear, fullscreen view.
Then when you remove this full screen view (fade out animation?) you don't have to mess with all the existing views again.
You shouldn't have to modify existing views just to display another. And what happens if one of those existing views really should have its interaction disabled? You will end up enabling the interaction when you dismiss your "modal" view.

How to put UIGestureRecognizer in front if several views with gestures overlaps

I have two views that have tap gesture recognizers attached. The first view accepts touches while the second one is hidden. After some time, I'm making the second (with attached gesture) view visible. The problem is that, still, only the touches of the first view are handled, despite the second view is in front :(
Sorry, forgot to put "user interaction enabled". I'm drawing my views and other stuff with interface builder, therefore I have missed that :)

How to recieve touches began event inside a subview?

I have a view containing two subviews(plain UIviews). The parent view recognizes touch events like touchesbegan ,ended, etc. but the sub view is not recognizing the touch event. How to make it recognize the touch event. Specifically i need only sub view to recognize touch events and not parent view. Thanks in advance.
UserInteractionEnabled is set to YES for the views.
There's two ways of dealing with this.
1) Detect the touches in your viewcontroller instead of in a view. You should be able to work out which view contains the point which was touched and from that can decide what to do with the touch (or just throw it away if it wasn't in either view).
2) Create a subclass of UIView and add these to your main view instead of just UIViews. Then you can detect the touches inside your subclass and deal with them accordingly.
Hope that helps.

Why is UIView exclusiveTouch property not blocking?

I am launching a simple UIView with a textField - let's call it orderSetNameView - upon a button tap. I wish to make this view modal, but without using a
[UIViewController presentModalViewContoller:animated:].
It seems I could simply set textInputView.exclusiveTouch = YES to achieve that.
Apple documentation says about exclusiveTouch:
A Boolean value indicating whether the receiver handles touch events
exclusively. If YES, the receiver blocks other views in the same
window from receiving touch events; otherwise, it does not. The
default value is NO.
I assume "same window" means same UIWindow, of which I have only one.
The problem is that when I instantiate my orderSetNameView, add it as a subview, and set exclusiveTouch = YES, touch events happen in all other views of my app, i.e., touch events in other views are not blocked as expected.
// ....
[self.view addSubview:self.orderSetNameView];
[self.orderSetNameView openWithAnimationForAnimationStyle:kMK_AnimationStyleScaleFromCenter];
}
// Set as modal
self.orderSetNameView.exclusiveTouch = YES;
Shouldn't orderSetNameView block touch events in all other views? What am I missing?
From Apple developer forums:
exclusiveTouch only prevents touches in other views during the time in which there's an active touch in the exclusive touch view. That is, if you put a finger down in an exclusive touch view touches won't start in other views until you lift the first finger. It does not prevent touches from starting in other views if there are currently no touches in the exclusiveTouch view.
To truly make this view the only thing on screen that can receive touches you'd need to either add another view over top of everything else to catch the rest of the touches, or subclass a view somewhere in your hierarchy (or your UIWindow itself) and override hitTest:withEvent: to always return your text view when it's visible, or to return nil for touches not in your text view.
Put this in AppDelegate or another file. Use this single time.
// Multi Touch Disable
UIView.appearance().isExclusiveTouch = true
UIButton.appearance().isExclusiveTouch = true