swift 的 guard & defer - 杨志平
guard 使用
1 | // 原始方法 (强解包可能会出现问题) |
懒加载
1 | //1.分析 NSArray 是一个闭包的返回值,而这是一个没有参数的闭包 |
调用的时候再在家初始化方法(懒加载)
1 | lazy private var underlineView: UIView = { |
defer 关键字
1 | /* |
嵌套枚举使用(简直就是动态Model)
1 | public enum MenuScrollingMode { |
iOS事件传递 & 事件响应 - 张超耀
什么是响应链
- 在我们点击屏幕的时候,iphone获取到了用户进行了“单击”这一行为,操作系统把包含这些点击事件的信息包装成UITouch和UIEvent形式的实例,然后找到当前运行的程序,逐级寻找能够响应这个事件的对象,直到没有响应者响应。这一寻找的过程,被称作事件的响应链
什么是响应者
- 在iOS中,能够响应事件的对象都是
UIResponder
的子类对象。UIResponder
提供了四个用户点击的回调方法,分别对应用户点击开始、移动、点击结束以及取消点击,其中只有在程序强制退出或者来电时,取消点击事件才会调用
1 | - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; - (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; - (void)touchesEstimatedPropertiesUpdated:(NSSet * _Nonnull)touches NS_AVAILABLE_IOS(9_1); |
- 我们可以看到方法接收两个参数,一个
UITouch
对象的集合,还有一个UIEvent
对象。这两个参数分别代表的是点击对象和事件对象
事件对象
- iOS使用
UIEvent
表示用户交互的事件对象,在UIEvent.h
文件中,我们可以看到有一个UIEventType
类型的属性,这个属性表示了当前的响应事件类型。分别有多点触控、摇一摇以及远程操作(在iOS之后新增了3DTouch
事件类型)。在一个用户点击事件处理过程中,UIEvent
对象是唯一的
点击对象
UITouch
表示单个点击,其类文件中存在枚举类型UITouchPhase
的属性,用来表示当前点击的状态。这些状态包括点击开始、移动、停止不动、结束和取消五个状态。每次点击发生的时候,点击对象都放在一个集合中传入UIResponder
的回调方法中,我们通过集合中对象获取用户点击的位置。其中通过- (CGPoint)locationInView:(nullable UIView *)view
获取当前点击坐标点,- (CGPoint)previousLocationInView:(nullable UIView *)view
获取上个点击位置的坐标点。为了确认UIView确实是通过UIResponder的点击方法响应点击事件的,我创建了UIView的类别,并重写
+ (void)load
方法,使用method_swizzling
的方式交换点击事件的实现 ——参照最下方demo
响应链传递
- 上面已经介绍了某个控件在接收到点击事件时的处理,那么系统是怎么通过用户点击的位置找到处理点击事件的view的呢?
- 存在着这么一个方法:
- (nullable UIResponder *)nextResponder
,通过方法名我们不难发现这是获取当前view的下一个响应者,逐级获取下一响应者,直到没有下一个响应者位置