问题
I have a UIView subclass (CustomView
for purposes of this question) that has its own handling of all touches
events (Began, Moved, Ended, Cancelled). I also have a UIButton
that is a sibling of CustomView
that overlaps it.
For example, my view hierarchy looks like this:
- UIView (Controller's view)
- CustomView with frame (0, 0, 300, 300)
- UIButton with frame (0, 0, 100, 50)
I would like the CustomView to capture touch events once the user has dragged out of the UIButton. Through debug logging, it appears that the UIControlEventTouchDragExit
event is the one to intercept (though it doesn't fire until the touch is around 100 pixels away from the button, but that is not important to this question).
Ideally, when the drag exit event is fired, the button would stop receiving touch move events, the CustomView would get a touchesBegan
event (even if I need to fake one myself somehow), and all future touch events (touchesMoved
, etc) would be sent to the CustomView.
I have tried the following, and it doesn't have any effect:
-(void)btnTouchDragExit:(id)sender
{
UIButton * btn = sender;
[btn resignFirstResponder];
[customView becomeFirstResponder];
}
I think the underlying UITouch
object (which is consistent across touch events) is not being retargeted to point at the CustomView. How can I achieve the desired effect?
回答1:
Just use hitTest:withEvent: to figure out what view "should" be receiving the event, then forward on the event to the appropriate view. You might have to do a little bit of dancing around to intercept events before they go to the button, but this is what hitTest:withEvent: was made for.
回答2:
you have to override canBecomeFirstResponder
to return YES otherwise becomeFirstResponder
does nothing. This is already done on UIControl
s, but not on UIView
s
来源:https://stackoverflow.com/questions/1418685/how-to-transfer-first-responder-from-one-uiview-to-another