iOS Development: On the response to the event delivery chain

basic concept

Responder:

In iOS, the responder is UIResponder subclass object can respond to events, such as UIButton, UIView like.

Response chain:

Chain response responder (UIResponse subclass) consisting of linked together. By default, a response by a first responder chain, as well as among all the application object with the composition of responders.

Event delivery:

After obtaining the response chain, the first event to the application's response is the transfer of event delivery process.

Response chain

Process performed responder chain

1, looking for first responders

View along the tree structure from the root node through all the child controls, by hitTest:withEvent:the method to find the first responder, the responder series from a first responder to the application object that is responsive chain

2, looking for the ultimate response object

The response from the first responder incident response along the chain transfer, if the first responder fails to respond will continue to be transmitted to the parent control, until you find the final response object.

How to look for first responders

1, when the program iOS touch event occurs, the system will use Runloop UIApplication event was added to the job queue, the specific process, reference may further be appreciated runloop
2, UIApplication touch event to distribute UIWindow, then turn downward distributed UIWindow the UIView
. 3, UIView calling hitTest:withEvent:method and see if he could handle the event, as well as whether touch points in on itself.
4, if the conditions are met, then traverse the child controls on the UIView. Repeat the above operation.
5 child controls until you find a top-level satisfies the condition (both handle touch events, touch points and above), and this is the first responder child controls we need to find.

hitTest: withEvent: process flow

(上面的查找其实就是由该方法递归调用实现的)
1、首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内; 
2、若返回NO,则hitTest:withEvent:返回nil; 
3、若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕; 
4、若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束; 
5、如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。 

hitTest:withEvent:方法的伪代码

//返回最适合处理事件的视图,最好在父视图中指定子视图的响应
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.userInteractionEnabled || !self.hidden || self.alpha <= 0.01) {
        return nil;
    }
    
    if ([self pointInside:point withEvent:event]) {
        
        for (UIView *subView in [self.subviews reverseObjectEnumerator]) {
            CGPoint subPoint = [subView convertPoint:point fromView:self];
            
            UIView *bestView = [subView hitTest:subPoint withEvent:event];
            if (bestView) {
                return bestView;
            }
        }
        return self;
    }

    return nil;
}

事件的响应流程

通过上面的 hitTest:withEvent: 寻找到第一响应者后,需要逆着寻找第一响应者的方向(从第一响应者->UIApplication)来响应事件。

流程如下

1.首先通过 hitTest:withEvent: 确定第一响应者,以及相应的响应链
2.判断第一响应者能否响应事件,如果第一响应者能进行响应则事件在响应链中的传递终止。如果第一响应者不能响应则将事件传递给 nextResponder也就是通常的superview进行事件响应
3.如果事件继续上报至UIWindow并且无法响应,它将会把事件继续上报给UIApplication
4.如果事件继续上报至UIApplication并且也无法响应,它将会将事件上报给其Delegate
5.如果最终事件依旧未被响应则会被系统抛弃

需要思考的点

为什么会出现在响应链中,但是无法响应事件。

  1. Here misleading, is looking for first responders process is actually only determine whether the ability to view the response of the touch event, but did not determine whether you can respond to the event.
  2. First responder specific event processing is determined in the process carried out in response to the event.

Checkpoints view does not respond

  1. hidden = YES view is hidden
  2. userInteractionEnabled = NO does not accept the response event
  3. alpha <= 0.01, transparent view does not receive a response event
  4. Beyond the scope of the parent view subview
  5. Which must respond to other views view of the covered
  6. Whether to rewrite the parent view and its own method hitTest
  7. Whether to rewrite the parent view and its own method pointInside

Reference article

Some understanding iOS incident response chain transfer of
the Using Responders and Events at The Responder Chain to the Handle
iOS response chain and delivery mechanisms

Guess you like

Origin www.cnblogs.com/darkwing/p/11223043.html
Recommended