TabBar再次点击实现刷新+UIRefreshControl使用踩坑

2018 年 3 月 30 日 CocoaChina YungFan

需求


之前已经实现了自定义TabBar,如图所示:


自定义TabBar.jpeg


现在需要实现一个类似今日头条TabBar的功能 —— 如果继续点击当前TabBar的选中项,那么该界面需要刷新UITableView。


分析


既然已经自定义了TabBar,那么最简单的就是在自定义中给TabBar中需要的UITabBarButton添加事件 —— 点击就发送通知,并且将当前的索引传出去。对应的界面监听通知,拿到索引比对,如果和当前索引一致,就执行对应的操作。


实现


1.自定义TabBar的layoutSubviews中绑定事件


- (void)layoutSubviews

{

    

    [super layoutSubviews];

    for (UIButton * tabBarButton in self.subviews) {

            

        if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {

            

            //监听tabbar的点击

            //绑定tag 标识

            tabBarButton.tag = index;

            

            //监听tabbar的点击

            [tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchUpInside];

            

        }

    }

}


2.监听事件,发送通知



- (void)tabBarButtonClick:(UIControl *)tabBarBtn{

    

    //判断当前按钮是否为上一个按钮

    //再次点击同一个item时发送通知出去 对应的VC捕获并判断

    if (self.previousClickedTag == tabBarBtn.tag) {

        

        [[NSNotificationCenter defaultCenter] postNotificationName:

         @"DoubleClickTabbarItemNotification" object:@(tabBarBtn.tag)];

    }

    self.previousClickedTag = tabBarBtn.tag;

}


3.对应的UIViewController监听通知


- (void)viewDidLoad {

    [super viewDidLoad];

    

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(doubleClickTab:) name:@"DoubleClickTabbarItemNotification" object:nil];

    

}


4.监听到通知,比对后执行操作


-(void)doubleClickTab:(NSNotification *)notification{

    

    //这里有个坑 就是直接用NSInteger接收会有问题 数字不对

    //因为上个界面传过来的时候封装成了对象,所以用NSNumber接收后再取值

    NSNumber *index = notification.object;

    

    if ([index intValue] == 1) {

        //刷新

    }

    

}


问题描述


实现了TabBar的点击刷新以后,开始继续写完成功能,刷新UITableView,于是考虑到iOS 10以后,UIScrollView已经有UIRefreshControl的属性了,干脆用自带的写。于是就有了如下的代码:


1.添加UIRefreshControl到UITableView上去


UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

    

refreshControl.tintColor = [UIColor grayColor];

    

refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"下拉刷新"];

    

[refreshControl addTarget:self action:@selector(refreshTabView) forControlEvents:UIControlEventValueChanged];


self.newsTableView.refreshControl = refreshControl;


2.下拉刷新事件


-(void)refreshTabView

{

    //添加一条数据

    [self.newsData insertObject:[self.newsData firstObject] atIndex:0];


    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        

        [self.newsTableView reloadData];

        

        if ([self.newsTableView.refreshControl isRefreshing]) {

            

            [self.newsTableView.refreshControl endRefreshing];

        }

    });

}


3.TabBar点击事件


-(void)doubleClickTab:(NSNotification *)notification{

    

    //这里有个坑 就是直接用NSInteger接收会有问题 数字不对

    //因为上个界面传过来的时候封装成了对象,所以用NSNumber接收后再取值

    NSNumber *index = notification.object;

    

    if ([index intValue] == 1) {

        //刷新

        [self.newsTableView.refreshControl beginRefreshing];

        

    }

    

}


此时的效果如下,直接下拉刷新可以,但是点击TabBar不可以:


刷新异常情况.gif


分析问题


经过Google帮助,终于知道原因,因为系统自带的UIRefreshControl有两个陷阱:


  1. 调用-beginRefreshing方法不会触发UIControlEventValueChanged事件;

  2. 调用-beginRefreshing方法不会自动显示进度圈。


也就是说,只是调用-beginRefreshing方法是不管用的,那么对应的需要做两件事:


  1. 手动设置UIRefreshControl的事件;

  2. 手动设置UITableView的ContentOffset,露出进度圈。


解决问题


只需要修改上面第3步中的代码如下:


-(void)doubleClickTab:(NSNotification *)notification{


    //这里有个坑 就是直接用NSInteger接收会有问题 数字不对

    //因为上个界面传过来的时候封装成了对象,所以用NSNumber接收后再取值

    NSNumber *index = notification.object;

    

    if ([index intValue] == 1) {

        //刷新

        //animated不要为YES,否则菊花会卡死

        [self.newsTableView setContentOffset:CGPointMake(0, self.newsTableView.contentOffset.y - self.newsTableView.refreshControl.frame.size.height) animated:NO];

        

        [self.newsTableView.refreshControl beginRefreshing];

        

        [self.newsTableView.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];

    }

    

}


最终效果:



作者:YungFan

链接:https://www.jianshu.com/p/410c87b4f3ef

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


相关推荐:

神气的 iOS 打包

iOS 不规则(多边形)图形切图

iOS重构实践


登录查看更多
0

相关内容

Eurographics是唯一在欧洲范围内真正的专业计算机图形协会。它汇集了来自世界各地的图形专家,该协会支持其成员推进计算机图形学以及多媒体,科学可视化和人机界面等相关领域的最新技术水平。通过其全球成员资格,EG与美国,日本和其他国家/地区的发展保持着密切联系,从而促进了全球范围内科学技术信息和技能的交流。 官网地址:http://dblp.uni-trier.de/db/conf/eurographics/
【ICML2020】对比多视角表示学习
专知会员服务
52+阅读 · 2020年6月28日
【阿里巴巴-CVPR2020】频域学习,Learning in the Frequency Domain
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
《动手学深度学习》(Dive into Deep Learning)PyTorch实现
专知会员服务
119+阅读 · 2019年12月31日
Keras作者François Chollet推荐的开源图像搜索引擎项目Sis
专知会员服务
29+阅读 · 2019年10月17日
Stabilizing Transformers for Reinforcement Learning
专知会员服务
58+阅读 · 2019年10月17日
iOS自定义带动画效果的模态框
CocoaChina
7+阅读 · 2019年3月3日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
教你实现超流行的骨架屏预加载动态效果
IMWeb前端社区
73+阅读 · 2018年11月27日
Github 项目推荐 | 用 PyTorch 0.4 实现的 YoloV3
AI研习社
9+阅读 · 2018年8月11日
为什么你应该学 Python ?
计算机与网络安全
4+阅读 · 2018年3月24日
设计和实现一款轻量级的爬虫框架
架构文摘
13+阅读 · 2018年1月17日
利用 TensorFlow 实现排序和搜索算法
机器学习研究会
5+阅读 · 2017年11月23日
tensorflow LSTM + CTC实现端到端OCR
机器学习研究会
26+阅读 · 2017年11月16日
Arxiv
21+阅读 · 2019年3月25日
Arxiv
3+阅读 · 2019年3月1日
VIP会员
相关VIP内容
【ICML2020】对比多视角表示学习
专知会员服务
52+阅读 · 2020年6月28日
【阿里巴巴-CVPR2020】频域学习,Learning in the Frequency Domain
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
《动手学深度学习》(Dive into Deep Learning)PyTorch实现
专知会员服务
119+阅读 · 2019年12月31日
Keras作者François Chollet推荐的开源图像搜索引擎项目Sis
专知会员服务
29+阅读 · 2019年10月17日
Stabilizing Transformers for Reinforcement Learning
专知会员服务
58+阅读 · 2019年10月17日
相关资讯
iOS自定义带动画效果的模态框
CocoaChina
7+阅读 · 2019年3月3日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
教你实现超流行的骨架屏预加载动态效果
IMWeb前端社区
73+阅读 · 2018年11月27日
Github 项目推荐 | 用 PyTorch 0.4 实现的 YoloV3
AI研习社
9+阅读 · 2018年8月11日
为什么你应该学 Python ?
计算机与网络安全
4+阅读 · 2018年3月24日
设计和实现一款轻量级的爬虫框架
架构文摘
13+阅读 · 2018年1月17日
利用 TensorFlow 实现排序和搜索算法
机器学习研究会
5+阅读 · 2017年11月23日
tensorflow LSTM + CTC实现端到端OCR
机器学习研究会
26+阅读 · 2017年11月16日
Top
微信扫码咨询专知VIP会员