引言
demo案例功能:
- 当进入首页时提示用户再次点击tabBar可刷新界面数据
- 刷新数据当同时旋转tabbar的图片
从CSDN下载完整地址demo :https://download.csdn.net/download/u011018979/15504711
- 文章同步到
#小程序:iOS逆向
,更好的阅读体验和更多内容请关注#小程序:iOS逆向
,只为你呈现有价值的信息,专注于移动端技术研究领域。- 应用场景:适用于购物类app的首页tabBar,以及购物券类app的首页tabBar
- 特色功能:在更新数据期间旋转tabbar的icon
- 视频演示效果可从blink查看:https://blink.csdn.net/details/1175811
- 如果遇到资源下载地址404,请通过公众号联系我
I、核心实现
进入首页时再次点击tabBar可刷新界面数据
1.1 在selectedViewController中记录上一次按钮的点击,用于数据刷新
- 新增一个属性 记录上一次被点击按钮的tag
/** 记录上一次被点击按钮的tag */ @property (nonatomic, assign) NSInteger previousClickedTag;
1.2 实现 UITabBarControllerDelegate 进行数据刷新
- 将selectedViewController设置为tabBarController的delegate
self.tabBarController.delegate = self; - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
- 记录上一次按钮的点击,进行数据刷新
- (void)viewDidLoad { [super viewDidLoad]; self.automaticallyAdjustsScrollViewInsets = NO; self.view.backgroundColor = HWColor(245, 245, 245); [self setNavigationContent]; // self.tabBarItem addObserver:<#(nonnull NSObject *)#> forKeyPath:<#(nonnull NSString *)#> options:<#(NSKeyValueObservingOptions)#> context:<#(nullable void *)#> self.tabBarController.delegate = self; self.previousClickedTag = 100;//默认没有点击任何tabbar } - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{ if (tabBarController.selectedIndex == 0 && [self.tabBarItem.title isEqualToString:homeTabbarSelectedTitle]) { //进行数据刷新 if ( self.previousClickedTag == tabBarController.selectedIndex ) {//进行了第二次点击 [self.tableView.mj_header beginRefreshing]; } } self.previousClickedTag = tabBarController.selectedIndex;//记录上一次按钮的点击 }
1.3 在UITabBarDelegate代理方法实现UITabBarItem样式的动态更换
- 处理选中/未选中的UITabBarItem 样式
通过代理方法didSelectItem修改UITabBarItem的title ,达到选中之后和未选中的title不一样的效果
- 切换到首页时title为刷新,提示用户再次点击tab刷新界面数据
- 未选择首页tab时的title为首页
NSString * const GYQhomeTabbarTitle = @"首页"; NSString * const GYQhomeTabbarSelectedTitle = @"刷新"; - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{ if ([item.title isEqualToString:GYQhomeTabbarTitle]) { item.title = GYQhomeTabbarSelectedTitle; }else{ // 切换到其他子Tab时,将首页tab的title刷新改为《首页》 for (UITabBarItem *childView in tabBar.items) { if ([childView.title isEqualToString:GYQhomeTabbarSelectedTitle] && childView != item) { childView.title = GYQhomeTabbarTitle; } } } //———————————————— //版权声明:本文为CSDN博主「#公众号:iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 //原文链接:https://blog.csdn.net/z929118967/article/details/77885824 }
II、旋转tabbar 的图片
/** 是否刷新tabbar的图片 */ @property (nonatomic, assign) BOOL isreloadData; /** 存储UITabBarSwappableImageView,用于旋转tabbar的图片 */ @property (nonatomic,strong) UIView *imageView;
2.1 自定义UITabBar监听点击事件
- 监听UITabBar的点击事件,并传递icon所在视图给外围来实现旋转动画
// 遍历tabBar上的子控件,给"UITabBarButton"类型的按钮绑定动画效果事件 //(注意:遍历添加动画事件的时机是在layoutSubviews布局子控件方法中) - (void)layoutSubviews{ [super layoutSubviews]; for (UIControl *tabBarButton in self.subviews) { if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) { [tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchUpInside]; } } } // 动画效果(遍历UITabBarButton按钮的子控件, //如果需要对图片添加动画,寻找"UITabBarSwappableImageView"类型的图片子控件; ////如果需要对按钮下面的文字添加动画,寻找"UITabBarButtonLabel"类型的文字子控件即可). - (void)tabBarButtonClick:(UIControl *)tabBarButton { for (UIView *imageView in tabBarButton.subviews) { if ([imageView isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) { if (self.block) { self.block(imageView); } }}}
2.2 在更新数据期间旋转tabbar的icon
/** 是否更换tabbar的图片 */ @property (nonatomic, assign) BOOL isreloadData;
- 旋转tabbar的图片
self.previousClickedTag = 100;//默认没有点击任何tabbar HWTabBar *tabBar = (HWTabBar*)self.tabBarController.tabBar; [tabBar setBlock:^(UIView * imageView){ if (self.isreloadData) { self.imageView = imageView; CABasicAnimation * rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; //让其在z轴旋转 rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 ];//旋转角度 rotationAnimation.duration = 2; //旋转周期 rotationAnimation.cumulative = YES;//旋转累加角度 rotationAnimation.repeatCount = 100000;//旋转次数 [imageView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; } }]; } -(void)stopRotate { [self.imageView.layer removeAllAnimations]; } - (void)setIsreloadData:(BOOL)isreloadData{ _isreloadData = isreloadData; if (!isreloadData) { [self stopRotate]; } }
- 进行数据刷新
#pragma mark - tab点击刷新相关 /** 如果其他子tabBarController也是ViewController对象,self.tabBarItem.title的获取会不正确 */ - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{ if (tabBarController.selectedIndex == 0 && [self.tabBarItem.title isEqualToString:GYQhomeTabbarSelectedTitle]) {//// //(lldb) po [[self tabBarItem] title] //进行数据刷新 if ( self.previousClickedTag == tabBarController.selectedIndex ) {//进行了第二次点击 self.isreloadData = YES; // [tablview.mj_header beginRefreshing]; [self.webView reload]; // 数据更新完毕移除icon 旋转动画 } } self.previousClickedTag = tabBarController.selectedIndex;//记录上一次按钮的点击 }
- 数据更新完毕移除icon 旋转动画
- (void)webViewControllerDidFinishLoad:(AXWebViewController *)webViewController; { [self stopRotate]; } - (void)webViewController:(AXWebViewController *)webViewController didFailLoadWithError:(NSError *)error { [self stopRotate]; }
III 、注意事项
3.1 数据更新的注意事项
当多个视图进行切换的时候 判断存储数据模型数组的元素个数是否为空 保证只请求一次
- 为了保证第一次切换tab的时候 请求数据,可以根据模型数组的元素个数进行判断是否请求。
#warning 当多个视图进行切换的时候 判断存储数据模型数组的元素个数是否为空 保证只请求一次 if (self.titleHotIndexmodel.Count == 0) { 进行请求 }
3.2 实现 UITabBarControllerDelegate 进行数据刷新的注意事项
如果其他子tabBarController也是ViewController对象,self.tabBarItem.title的获取会不正确。所以推荐不同的tabBarController使用不同的class
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{ //(lldb) po [[self tabBarItem] title]