iOS 原生 App 是怎么 deselectRow 的

640?wx_fmt=jpeg

黑客技术 点击右侧关注,了解黑客的世界! 640?wx_fmt=jpeg

640?wx_fmt=jpeg

Java开发进阶 点击右侧关注,掌握进阶之路! 640?wx_fmt=jpeg

640?wx_fmt=jpeg

Linux编程 点击右侧关注,免费入门到精通! 640?wx_fmt=jpeg


作者 | 四娘,目前在格隆汇 iOS 组搬砖,Swift 系列语言爱好者,拖延癌末期患者。 
https://juejin.im/post/5c26dfe851882561431a4927


这两天偶然发现系统设置里 tableView deselectRow 的时机和效果都很特别,正常情况下我们的 deselect 操作都会在 didSelect 代理方法里执行,抑或者是更加细致一点,在 viewDidAppear 里完成。 但 iOS 原生的 App 说不,我还可以做得更好,这是系统设置里的效果: 640?wx_fmt=gif 侧滑返回时,deselect 动画会随着滑动手势的进度而改变,搜了一下,国内似乎没有太多相关的文章,并且我手头常用的几款软件都做到没有类似的效果。 搜了一下之后,发现国外的记录也很少,只有三篇文章记录了这个交互,其中写的比较详细的是这篇 The Hit List Diary #17 – clearsSelectionOnViewWillAppear[1]

转场动画的抽象 transitionCoordinator

这个交互其实是通过 UIViewController 的 transitionCoordinator 属性实现的,它的类型是 UIViewControllerTransitionCoordinator。 简单来说,它可以帮助我们在转场动画里加入一些自定义的动画,自定义动画的进度和生命周期会与转场动画保持一致,使用它可以达到更加自然和一致的转场效果,例如 push 动画里 navigationBar 背景颜色的变化,它提供了这几个方法供我们注册动画生命周期的回调:

 推荐大家去看一下 UIViewControllerTransitionCoordinator 这个协议的文档[2],这里摘录一段我觉得比较有趣的描述:
 
Using the transition coordinator to handle view hierarchy animations is preferred over making those same changes in the viewWillAppear(_:) or similar methods of your view controllers. The blocks you register with the methods of this protocol are guaranteed to execute at the same time as the transition animations. More importantly, the transition coordinator provides important information about the state of the transition, such as whether it was cancelled, to your animation blocks through the UIViewControllerTransitionCoordinatorContext object.
比起 viewWillAppear 和其它相似的 ViewController 生命周期函数,我们更加推荐使用 transitionCoordinator 处理视图层级的动画。你注册的函数可以保证与转场动画同时执行。更重要的是,transitionCoordinator 通过 UIViewControllerTransitionCoordinatorContext 协议提供了转场动画的状态等重要信息,例如动画是否已被取消等。
我由于最近业务的原因,第一个想起的就是 navigationBar,像是 barTintColor 这种属性就可以使用 transitionCoordinator 做到更加自然的动画转场。

实现与封装

我看了别人的文章并且尝试其它集中方式之后,感觉 transitionCoordinator 获取的最佳时机应该是 viewWillAppear,实现的逻辑大概是这样:

 如果把 transitionCoordinator 单纯地看成是一个动画抽象(抛开转场),我们希望跟随动画完成的操作就是 deselect,那么就可以更进一步地把这个 deselect 的操作封装到 UITableView 的 extension 里:
 

 接着只要在 viewWillAppear 里调用即可:
 
如果大家在项目里封装了自己的 TableViewController 并且规范使用的话,那要加入这个效果就很简单了。

结语

这是完整的示例[3]

参考

[1]http://mikeabdullah.net/thl-diary-17-clearsselectiononviewwillappear.html 
[2]https://developer.apple.com/documentation/uikit/uiviewcontrollertransitioncoordinator 
[3]https://github.com/kemchenj/DeselectRowTheBestWay 
[4]https://www.jianshu.com/p/6ec14f6762e5

 推荐↓↓↓ 

640?wx_fmt=jpeg

?16个技术公众号】都在这里!

涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。

640?wx_fmt=png万水千山总是情,点个 “ 在看” 行不行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值