iOS 动态更换UITabBarController的图标

简介: 更换tabbar的图表并不难, 难在动态更换时的思路, 我们可以先看看设置tabbarItem代码找思路:

更换tabbar的图表并不难, 难在动态更换时的思路, 我们可以先看看设置tabbarItem代码找思路:


UITabBarItem *item4 = [[UITabBarItem alloc] initWithTitle:@"我"
                                        image:[[UIImage imageNamed:@"tab_me_normal"]
                                 imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
                                selectedImage:[[UIImage imageNamed:@"tab_me_click"]
                       imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];


分析代码我们可以知道, 入口只有image和selectImage, 自己想出了两种方法, 如下:


  1. 及时更新法, 每次下载一套图片, 包括一个按钮的普通状态跟选中状态的图片, 下载完之后就及时更新, 下次再进入APP, 直接查找缓存, 不用再次下载 (此方法会出现的问题, 比如四个tabbarItem, 会出现图标不统一的问题, 即有的图标为新图标, 有的图标为老图标, 但是网络状态好的情况下, 一般不会出现这种问题, 再说更换tabbarItme的图标,不是经常性操作, 所以我目前就用的这种方法, 已经满足我的开发需要)


  1. 等待四套图标全部下载完, 再统一更新, 如果有部分图标下载不完成, 则不进行更换操作 (要与安卓商量好, 看看哪种方法适合, 我现在只写出上面那种方法, 这种方法请按上述方法进行扩展)

我写了一个Tabbar下载图片的工具类, 下面是.h文件 以及.m文件


#import <Foundation/Foundation.h>
#import "PORouterModel.h"
#import "SDImageCache.h"
#import "SDWebImageDownloader.h"
NS_ASSUME_NONNULL_BEGIN
@interface POTabbarTool : NSObject
/// 异步下载tabbar图片, (同时下载normal 跟 select图片, 两张图片都下载完成后 再触发最终的回调block)
/// @param routerModel tabbar的图片 要从routerModel.image中获取url
/// @param block 最终返回下载normal 跟 select图片
- (void)downloadImageWithPORouterMode:(PORouterModel *)routerModel AndReturnImageBlock:(void(^)(UIImage *normalImage, UIImage *selectImage, PORouterModel *routerModel))block;
@end
NS_ASSUME_NONNULL_END


#import "POTabbarTool.h"
@implementation POTabbarTool
/// 异步下载tabbar图片, (同时下载normal 跟 select图片, 两张图片都下载完成后 再触发最终的回调block)
/// @param routerModel tabbar的图片 要从routerModel.image中获取url
/// @param block 最终返回下载normal 跟 select图片
- (void)downloadImageWithPORouterMode:(PORouterModel *)routerModel AndReturnImageBlock:(void(^)(UIImage *normalImage, UIImage *selectImage, PORouterModel *routerModel))block{
    __block UIImage *needNormalImage;
    __block UIImage *needSelectImage;
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_enter(group);//开启任务一
    dispatch_group_async(group, queue, ^{
        [self toSearchCacheWithUrlString:routerModel.image2 completed:^(UIImage *image) {
            needNormalImage = image;
            dispatch_group_leave(group);//任务一完成
        }];
    });
    dispatch_group_enter(group);//开启任务二
    dispatch_group_async(group, queue, ^{
        [self toSearchCacheWithUrlString:routerModel.image1 completed:^(UIImage *image) {
            needSelectImage = image;
            dispatch_group_leave(group);//任务二完成
        }];
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        block(needNormalImage,needSelectImage,routerModel);//返回任务一跟任务二的数据
    });
}
- (void)toSearchCacheWithUrlString:(NSString *)urlString completed:(void (^)(UIImage *image))block{///<用SDImageCache去查找或下载图片, 最终返回图片
    UIImage *needImage;
    SDImageCache *normalImageCache = [SDImageCache sharedImageCache];
    needImage = [normalImageCache imageFromMemoryCacheForKey:urlString];//从内存中获取图片
    if (!needImage) {
        needImage = [normalImageCache imageFromDiskCacheForKey:urlString];//从硬盘中获取图片
        if (!needImage) {//如果都没有则下载图片
            [SDWebImageDownloader.sharedDownloader downloadImageWithURL:[NSURL URLWithString:urlString] completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
                if (image && finished) {
                    [normalImageCache storeImage:image forKey:urlString toDisk:YES completion:nil];//执行缓存图片 (包括缓存到内存和本地)
                    [normalImageCache storeImage:image forKey:urlString toDisk:YES completion:^{//本来有想过在这里直接处理过的图片, 但是发现图片会出问题, 所以处理图片的逻辑就放最外层了
                        block(image);
                    }];
                }
            }];
        }
        else{
            block(needImage);
        }
    }
    else{
        block(needImage);
    }
}


看懂上面的方法, 就可以任意扩展了, 在返回的block内更新tabbarItem的图标即可, 需要注意的是, 在返回的block内, 尽量少使用局部变量, 防止循环引用造成一些奇奇怪怪的问题


再多补充一些block内的伪代码


//声明, 不可在以下block内调用局部变量, 导致局部变量所对应的VC不释放, 会出现奇怪的tabbarUI问题, 现在以下block内写法没有问题
    WEAKSELF
    [self.tabbarTool downloadImageWithPORouterMode:routerModel AndReturnImageBlock:^(UIImage * _Nonnull normalImage, UIImage * _Nonnull selectImage, PORouterModel * _Nonnull routerModel) {
        UIImage *newNormalImage = [UIImage imageWithCGImage:normalImage.CGImage scale:2 orientation:normalImage.imageOrientation];
        newNormalImage = [newNormalImage sd_resizedImageWithSize:CGSizeMake(29, 29) scaleMode:SDImageScaleModeAspectFit];
        UIImage *newSelectImage = [UIImage imageWithCGImage:selectImage.CGImage scale:2 orientation:selectImage.imageOrientation];
        newSelectImage = [newSelectImage sd_resizedImageWithSize:CGSizeMake(29, 29) scaleMode:SDImageScaleModeAspectFit];
        weakSelf.needChangeVC.tabBarItem.image = [normalImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        weakSelf.needChangeVC.tabBarItem.selectedImage = [selectImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    }];



目录
相关文章
|
24天前
|
安全 数据安全/隐私保护 iOS开发
基于iOS的动态权限管理实现
【4月更文挑战第9天】 随着移动互联网的快速发展,用户对应用程序的隐私安全要求越来越高。在iOS平台中,如何实现动态权限管理成为了开发者关注的焦点。本文将详细介绍一种基于iOS的动态权限管理实现方法,通过使用Core Motion框架和Notification Center,实现对用户位置信息的实时监控和动态权限申请。
|
1月前
|
开发工具 Swift iOS开发
利用SwiftUI构建动态用户界面:iOS开发新范式
【4月更文挑战第3天】 随着苹果不断推进其软件开发工具的边界,SwiftUI作为一种新兴的编程框架,已经逐渐成为iOS开发者的新宠。不同于传统的UIKit,SwiftUI通过声明式语法和强大的功能组合,为创建动态且响应式的用户界面提供了一种更加简洁高效的方式。本文将深入探讨如何利用SwiftUI技术构建具有高度自定义能力和响应性的用户界面,并展示其在现代iOS应用开发中的优势和潜力。
|
10月前
|
Android开发 iOS开发 Windows
无影产品动态|iOS & Android客户端6.0.0版本发布,提升触控灵敏度,操作体验更丝滑
无影ios & Android客户端6.0.0版本发布!移动端触控体验更舒适,用户操作更便捷,一起来看看!
682 0
无影产品动态|iOS & Android客户端6.0.0版本发布,提升触控灵敏度,操作体验更丝滑
|
10月前
|
存储 缓存 iOS开发
iOS 轻量化动态图像下载缓存框架实现
日常开发过程中,图片的下载会占用大量的带宽,图片的加载会消耗大量的性能和内存,正确的使用图片显得尤为重要。 同样也经常需要在各类型控件上读取网络图片和处理本地图片,例如:UIImageView、UIBtton、NSImageView、NSButton等等。
iOS 轻量化动态图像下载缓存框架实现
|
10月前
|
C语言 C++ iOS开发
iOS中C++静态全局变量的动态初始化时序
一个由于C++初始化失败导致Realm初始化失败的Crash
138 1
|
iOS开发
iOS更新iOS15.0后APP图标变网格空白问题
iOS更新iOS15.0后APP图标变网格空白问题的解决
339 0
|
iOS开发
iOS 启动图设置及icon图标设置
OS 启动图设置及icon图标设置
744 0
iOS 启动图设置及icon图标设置
|
iOS开发
iOS开发 - 柱状图动态展现动画
iOS开发 - 柱状图动态展现动画
128 0
iOS开发 - 柱状图动态展现动画
|
编译器 iOS开发
IOS越狱开发(二)———APP开机自动启动并隐藏图标
IOS越狱开发(二)———APP开机自动启动并隐藏图标
249 0
IOS越狱开发(二)———APP开机自动启动并隐藏图标
|
定位技术 iOS开发
iOS模拟动态定位的测试方案
iOS模拟动态定位的测试方案
145 0
iOS模拟动态定位的测试方案