UIResponder Chain Explanation Needed
I'm having trouble getting my UIButtons
, UIScrollViews
etc working in this situation:
I have the base UIViewController
, which is the root controller of the UIWindow
.
Above that layer I have some other UIViews
added, which I will call the "Middle Layer View". And on the top I have another UIView
added for overlay objects.
The Middle Layer View is changed for different views regularly. The UIView
it uses is from a UIViewController
, made by a NIB file. Here's an example
if ( mode == eModeShowView1 )
UIViewController* nextController = [[UIViewController alloc] initWithNibName:@"View1"...
else if ( mode == eModeShowView2 )
UIViewController* nextController = [[UIViewController alloc] initWithNibName:@"View2"...
[UIView insertSubview:nextController.view below:m_overlayView];
Now, when I touch on screen, the first responder is obviously the OverlayView
or any UIResponder
on the OverlayView
that has been touched.
The UIEvent
of the touch input goes up the view chain bu开发者_C百科t seems to skip the Middle Layer View and the UIResponders
on that UIView
altogether. It jumps straight to the root UIViewController
.
Does anyone know what's going on here?
Could it be solved by somehow creating two UIEvents
? One for the Overlay View and one for the Middle Layer View? Is that possible? If so, how?
Any help would be most appreciated. Thanks, Rich
edit1 start:
you can put a UITapGestureRecognizer to the m_overlayView and initWithTarget:your-middleview action:some-method-in-middleview
Now, in your middleview you can identify recognizer.state as UIGestureRecognizerStateBegan, Ended etc and do what you want to do.
edit1 end:
You can debug it. Just use the logs in touchesbegan
in all your controllers. It will be clear by logs the sequence of touch responses.
Ok.. so this description of method from documentation might answer you. Your m_overlayView
and nextController.view
are regarding each other as siblings and not superview. So your touch on either of them will not be reported to the other but instead to the base superview
which is a common superview
to both the siblings.
Hence you are getting that the middle layer is being bypassed. Actually your middle-layer is a sibling and no more a superview. Hope that at least gives you some way ahead ;)
insertSubview:belowSubview:
Inserts a view below another view in the view hierarchy.
(void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview
Parameters:
view
The view to insert below another view. It’s removed from its superview
if it’s not a sibling of siblingSubview.
siblingSubview:
The sibling view that will be above the inserted view.
Discussion:
This method retains view and sets its next responder to the receiver, which is its new superview
.
Views can have only one superview. If view already has a superview
and that view is not the receiver, this method removes the previous superview
before making the receiver its new superview
.
精彩评论