> For the complete documentation index, see [llms.txt](https://philm.gitbook.io/philm-ios-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://philm.gitbook.io/philm-ios-wiki/mei-zhou-yue-du/xiang-ying-lian.md).

# 响应链

## Philm首页的拍摄按钮与滤镜是重叠的,且层级关系为拍摄按钮需要显示在最上层,同时要求滤镜可以滑动.这就需要使用响应链来处理重叠部分的响应顺序问题.

![](https://1795314173-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAdZ7gFz4IllRQpWbzu%2F-LAdZ8MxWrHaExfP4jSI%2F-LAdZVVWaeR1Oqh2mwAz%2F1.jpg?generation=1524337085721905\&alt=media)

## 当发生触摸事件时,hitTest会检查触摸点所在位置,并从最底层开始,递归找出当前所有的响应器,记录为responder chain,并找出层级在最上方的view作为第一响应者.

## 所以当前的响应器链为: UIKit –> active app’s event queue –> window –> root view —> vc.view — > 滤镜view—>拍摄按钮view.其中 最上层的拍摄按钮为当前的第一响应者.

## 如果这个hit-test找出的这个view不能处理事件,那么UIKit会从响应器链中寻找nextResponder,这个responder可以决定响应事件还是继续寻找nextResponder.以此类推,直到找到可以响应的responder或者响应链全部被查找完.通过这个原理,处理上述问题的解决方案是:使拍摄按钮的view不响应触摸事件,而是传递给下层的滤镜view. 以下为具体代码:

```
 //图层穿透
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if(hitView == self)
    {
        return nil;
    }
    return hitView;
}
```

## 另外通过响应链,我们也可以寻找当前最上层的controller,这样在view层也可以实现push/present或其他controller才能做的操作而不需要使用代理/block一层层传递.
