iOS 小知识: 再次点击tabBar刷新界面数据(更新数据期间旋转tabbar图标)【包含完整demo】

简介: iOS 小知识: 再次点击tabBar刷新界面数据(更新数据期间旋转tabbar图标)【包含完整demo】

引言

demo案例功能:

  1. 当进入首页时提示用户再次点击tabBar可刷新界面数据
  2. 刷新数据当同时旋转tabbar的图片

从CSDN下载完整地址demo :https://download.csdn.net/download/u011018979/15504711

  1. 文章同步到#小程序:iOS逆向,更好的阅读体验和更多内容请关注#小程序:iOS逆向,只为你呈现有价值的信息,专注于移动端技术研究领域。
  2. 应用场景:适用于购物类app的首页tabBar,以及购物券类app的首页tabBar
  3. 特色功能:在更新数据期间旋转tabbar的icon
  4. 视频演示效果可从blink查看:https://blink.csdn.net/details/1175811
  5. 如果遇到资源下载地址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刷新界面数据

image.png

  • 未选择首页tab时的title为首页

image.png

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]

see also

目录
相关文章
|
3月前
|
语音技术 开发工具 图形学
Unity与IOS⭐一、百度语音IOS版Demo调试方法
Unity与IOS⭐一、百度语音IOS版Demo调试方法
|
2月前
|
iOS开发
iOS超出父控件范围无法点击问题
iOS超出父控件范围无法点击问题
140 58
|
2月前
|
iOS开发
iOS超出父控件范围无法点击问题
iOS超出父控件范围无法点击问题
|
3月前
|
iOS开发 开发者
iOS平台RTMP|RTSP播放器如何实时回调YUV数据
我们在做RTMP、RTSP播放器的时候,有开发者需要自己处理拉取到的YUV数据,做二次分析之用,为此,我们做了以下的设计:InitPlayer之后,再调用SmartPlayerStart()接口之前,设置yuv数据回调即可。
|
5月前
|
编解码 安全 Android开发
探索iOS与Android开发的差异:从界面到性能
【6月更文挑战第10天】在移动应用开发的广阔天地中,iOS和Android两大平台各占山头,它们在设计理念、用户体验、性能优化等方面展现出独特的魅力。本文将深入探讨这两大系统在开发过程中的主要差异,从用户界面设计到性能调优,揭示各自背后的技术逻辑与创新策略,为开发者提供全面的视角和实用的开发指南。
|
6月前
|
安全 Swift iOS开发
【Swift 开发专栏】Swift 与 UIKit:构建 iOS 应用界面
【4月更文挑战第30天】本文探讨了Swift和UIKit在构建iOS应用界面的关键技术和实践方法。Swift的简洁语法、类型安全和高效编程模型,加上与UIKit的紧密集成,使开发者能便捷地创建用户界面。UIKit提供视图、控制器、布局、动画和事件处理等功能,支持灵活的界面设计。实践中,遵循设计原则,合理组织视图层次,运用布局和动画,以及实现响应式设计,能提升界面质量和用户体验。文章通过登录、列表和详情界面的实际案例展示了Swift与UIKit的结合应用。
294 1
|
6月前
|
Java iOS开发
iOS的数据序列化(又称持久化)的两类使用方式
iOS的数据序列化(又称持久化)的两类使用方式
65 0
|
6月前
|
移动开发 小程序 API
uniapp通过蓝牙传输数据 (ios)
uniapp通过蓝牙传输数据 (ios)
319 1
|
6月前
|
Java 开发工具 Android开发
SLS:使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践
本文介绍了使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践。
441 7
SLS:使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践
|
iOS开发 设计模式