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

需求





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

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

自定义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不可以:

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

刷新异常情况.gif



分析问题



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

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

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



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

  • 手动设置UIRefreshControl的事件;

  • 手动设置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];

        }

        

    }



    最终效果:

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



    作者:YungFan

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

    來源:简书

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

    相关推荐:

    神气的 iOS 打包

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

    iOS重构实践

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