美文网首页iOS Developer
iOS 列表视图最简洁的回滚到顶部的解决方案

iOS 列表视图最简洁的回滚到顶部的解决方案

作者: topCoder | 来源:发表于2016-05-24 14:37 被阅读550次

    iOS中的列表视图自带回滚到顶部的功能,就是设置scrollsToTop属性为YES即可,但是当控制其中有多个视图的时候,就不灵了,我也看过网上给过的解决方案,需要设置其他UIScrollView视图的scrollsToTop属性为NO才奏效。这样个人感觉很麻烦,为什么不用黑魔法呢,哈哈,请看我的解决方案。

    1. 首先我们得找到系统的statusBar,怎么找呢?

    系统提供了我们设置StatusBar的各种属性,例如常用的  [UIApplication sharedApplication].statusBarHidden所以我怀疑statusBar会是UIApplication的私有化的属性,然后进去了UIApplication的API文档,找到了@class UIStatusBar。所以我个人认为statusBar应该是[UIApplication sharedApplication] 这个单例类所持有的视图(应该是继承于UIView),所以statusBar应该是具有唯一性的。然后顺藤摸瓜,我们通过Runtime来扒一扒。先找到对应的type,找到对应的那么,最后通过KVC,拿到statusBar对象。

    2. 在什么地方调用 statusBarView 方法呢?个人认为得在UIViewController中调用,一般逻辑处理都在控制器中进行。

    最后选择在控制器的生命周期方法viewDidLoad 中调用,只能用方法交换来处理了,不然太low了,所以得用category了。

    在load类方法中我们得做一个方法交换了。

    load中的方法是我对NSObject的category中做的交换方法所用的。

    这样我就可以在交换后的方法 swizz_viewDidLoad 中获取statusBar了,取出statusBar后,我又对UIStatusBar中的变量遍历打印,没有发现点击手势之类的属性,好吧,只能我自己添加了。

    3.  很明显思路已经清晰了,我们可以在手势的点击方法中做相关的处理,我目前是在UIViewController的categroy中添加Block属性,category中动态添加属性只能通过关联引用了。

    最后我们在控制器中的属性Block回调中就可以通过设置UIScrollView的setContentOffset 为CGPointZero 来达到回滚到顶部的效果啦!!! 逻辑处理在UIViewController中,需要哪个UIScrollView回滚,直接调用setContentOffset 方法即可,不用管理其他视图的,简单粗暴哦。

    Note: 以下是新添加的内容,有关手势的移除问题:

    在项目中运用后,发现当控制器移除后,再次点击statusBar会出现这种内存错误 -[XXXController tapGestureAction]: message sent to deallocated instance 0x1509445e0,很明显是控制器移除了,但是点击手势还是存在的,当向一个释放掉的对象发送消息时,会出现这种Crash: EXC_BAD_ACCESS(code=1,address=0x0) 。

    所以我们应该在控制器的生命周期结束之前,把手势的响应方法移除掉才行。

    必须混写dealloc方法了,注意直接混写dealloc是会报错的,ARC forbids use of 'dealloc' in a @selector.

    so, 换一种方式,在load方法中这样写:

    [self swizzWithClass:[self class] originSel:NSSelectorFromString(@"dealloc") newSel:@selector(swizz_dealloc)];

    然后在混写后的方法中,对相应的点击手势做一个移除操作就OK了。

    以上是全部内容,有异议或者有更好的建议的,欢迎大家指正,谢谢!

    相关文章

      网友评论

      • 广锅锅:我之前使用过一个三方库:当界面上有很多scrollView时,可以实现点击statusBar使TableView回到顶部。
        但是这个库有个缺陷:当从其他app跳转到我的app,此时在statusBar左边有个返回按钮 "< 某某app",这个时候,我点击这个按钮是没有任何反应的。
        看了你的方法,我觉得那个库实现的原理应该是与你类似的。因为整个Bar都被手势覆盖了。
        我觉得最合理的黑魔法应该是:使用Method Swizzle在UIScrollView的init方法结束后,把他们的scrollsToTop都设为NO。再设置你想要回到顶部的那个scrollView的属性为YES。

      本文标题:iOS 列表视图最简洁的回滚到顶部的解决方案

      本文链接:https://www.haomeiwen.com/subject/ghdzrttx.html