Does UserInteractionEnabled work like Alpha for a UIView Hierarchy? - ios

I know that if I set the Alpha for a parent UIView to to 0 that all its children are also 'invisible'. Is it also true that setting a parent UIView's UserInteractionEnabled to NO affect it's children in anyway? In other words will making a superView untouchable make its subViews untouchable?

Yes, but not in the same way. Basically, if you set a UIView.userInteractionEnable to NO, It will no longer process touch events, which means it will not be passing events to sub-views. You can, however, set userInteractionEnable to NO for sub-views with out impacting parent views or peer views.

Related

UIStackViews are overlapping and therefore the button doesn't work

I have two UIStackViews and they animate so when it is supposed to be tapped the overlapping shouldn't exist or be a problem anymore, but it still is.
Is there a way to still accept touches on a control that's covered by another control?
This is how it looks without running it...when it loads..the square stackview in the middle stays put and the other one which is still behind it...grows adn the buttosn aren't covered anymore
You can set userInteractionEnabled to false on the covering views
Or if you want both to receive events, set exclusiveTouch to false, and userInteractionEnabled to true.

Disable touching view through subView

I'm trying to make my first game using SpriteKit + Swift.
The problem I'm trying to solve right now is that if I add to my main SKView a SUBVIEW without any buttons just with a background color and size and touch it, my main view handles this touch like there is no subview at all.
So the subView of type UIView like doesn't exist for UITapGestureRecognizer of parent view. And the only way I found to solve it, is to put a subView-sized button on the subview without text and handler. But this way looks creepy...
It could be that your subView (or one of its parents views) has the userInteractionEnabled set to false. UIView has the userInteractionEnabled set to true by default, but for example UIImageView (which is a subclass of UIView) has the userInteractionEnabled set to false by default.
When set to NO, user events—such as touch and keyboard—intended for
the view are ignored and removed from the event queue. When set to
YES, events are delivered to the view normally. The default value of
this property is YES.
(...)
Note
Some UIKit subclasses override this property and return a different
default value. See the documentation for that class to determine if it
returns a different value.
See Apple docs for more info.
It could be not your subView by itself, but one of its parents views too, because this setting is propagated down.
If set to NO, this view (along with its subviews) is excluded from
receiving touches. Touches on this view or one of its subviews "fall
through" to a view behind it.
source: Programming iOS by Matt Neuburg
For more, check On iOS, if a superview's userInteractionEnabled is NO, then all subviews are disabled as well?

Receiving touch events in hidden UIView?

Is it possible in some way to receive and respond to touch events from a UIView that is not visible. I tried -- as well as read from the Apple docs -- that simply setting 'hidden' will not work. I'm looking for an alternative to achieve the same effect.
A hidden view disappears from its window and does not receive input events. It remains in its superview’s list of subviews, however, and participates in autoresizing as usual. Hiding a view with subviews has the effect of hiding those subviews and any view descendants they might have. This effect is implicit and does not alter the hidden state of the receiver’s descendants.
if a view has set userInteractionEnabled to YES it will be touchable when hidden. Try to experiment with UIButton for example.
Make it transparent, not hidden (with alpha set to 0). If that doesn't work, make it nearly transparent (alpha set to 0.1).

How to handle tap out of custom view frame

I have a custom view with custom popup on it (added as subview).
When I'm opening this popup it's frame goes out of parent view frame.
And I can't handle user interaction on the outside popup view.
How can I fix it?
I thought about this plan:
1. Add custom view on superview;
2. Add custom popup on superview (right the position where it should be on custom view)
But i think it isn't right way.
Any suggestions?
To be honest I haven't tried it yet, but you might have luck with adding a custom view on the superview and overriding pointInside:withEvent:.
I'm thinking the superview is recognizing that the tap doesn't occur inside its own frame, so it won't even check its subviews. But if you override pointInside:withEvent: you can check that the tap location is inside the subviews frame regardless of whether it's inside the superview's frame.
If that doesn't work, you might have to override hitTest:withEvent: also (or instead of). I can try to work out an example if you need more direction than that.
This Technical Q&A might help you out https://developer.apple.com/library/ios/qa/qa2013/qa1812.html
What you mention is actually the right approach: you should have a superview (it can be transparent (clear color)) that contains both the custom view and the popup inside of its frame.
On iOS, touch events are sent to a receiver at a low level in your visual hierarchy (I believe this is your Window to be specific). This receiver calls HitTest on its subviews to figure out which one to forward the event to. This happens recursively until the HitTest fails on all of a view's subviews. Then the parent of those subviews handles (or doesn't handle) the touch event.
But before the HitTest implementation even starts calling HitTest on the subviews, it calls PointInside on the superview. If PointInside returns false for the touch point, then HitTest returns null.
So overriding PointInside on the class that you call SuperView may solve the problem you're facing, but not necessarily. You may need to override PointInside on the superview of SuperView, and then on that view's superview, and so on. This is not a good solution, it is brittle and hacky. Overriding PointInside does have its uses, but this isn't one.
So try to keep all of your views within the bounds of their superview, even if you have to make a transparent superview that has no other reason to exist other than to contain other views. That's fine.

controlling orientation changes from within a subview

Have a very large program where there is always a superview that just encompasses a custom segment controller. This view sits at the top of screen and controls navigation in several ways.
So the problem arose in only a selected few view controllers where everything was 100% programmaticly created. Essentially CGRect are not being defined in the property dynamic coordinates. But are not being recalculated on orientation change. Does anyone have a simple way to control this in the subview? I'm about to code something in the superview to pass to orientation to other subviews.. but there has to be a better way. Ideas?
Couple of pointers:
You can use auto-resizing masks to determine what happens to your views when their bounds change (ie, when the orientation changes). So UIViewAutoresizingFlexibleWidth means your view will 'stretch' proportionally with the superview when the bounds are changed. UIViewAutoresizingFlexibleLeftMargin means your view will effectively be right-aligned, as the left margin will adjust according to the width, etc etc.
Sometimes auto-resizing masks aren't enough - perhaps you have to change the view's content on an orientation, or do a complex animation. In this case, you use the willAnimateRotationToInterfaceOrientation method in your view controller. Your subviews might have a custom adjustForOrientation method that you've written that you can trigger when willAnimateRotation... is called.
Finally, on iOS 5 you can actually nest view controllers inside of view controllers, in which case orientation events get passed through automatically...but this is probably needlessly complex for what you're trying to do.

Resources