版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.10.21 |
前言
目前市面上的APP架构基本都是一样的,都是
UITabBarController
作为根控制器,然后添加UINavigationController
作为子控制器,然后再添加几个主页控制器,作为导航的根控制器。这里有一个问题就是子控制器的生命周期问题。
问题引出
关于注意UITabBarController
子控制器生命周期的问题,还是在iOS11以后,在iOS11正式版出来以后,我就发现一个问题,凡是从几个主页面到二级页面的控制器,UITabBar
都会先显示然后隐藏,做大约0.5s的一个动画,于是,我就要修改,想到第一个方案就是生命周期方法中强制隐藏和显示UITarBar。
这里我就在项目中- (void)viewWillAppear:(BOOL)animated
中强制显示和在- (void)viewWillDisappear:(BOOL)animated
中进行强制隐藏,但是发现还是不多,通过打断点,我发现原来是生命周期的问题。
素材准备
下面我们就看一下准备的实现素材。下面直接看代码。
1. AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
JJTabBarVC *tabBarVC = [[JJTabBarVC alloc] init];
self.window.rootViewController = tabBarVC;
[self.window makeKeyAndVisible];
return YES;
}
2. JJTabBarVC.m
#import "JJTabBarVC.h"
#import "ZBLivelistController.h"
#import "ZBVideoAlbumVC.h"
#import "ZBShortVideoVC.h"
@interface JJTabBarVC ()
@end
@implementation JJTabBarVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
[self addChildViewController];
}
#pragma mark - Object Private Function
- (void) addChildViewController
{
[self addChirdViewControllerWithClass:[[ZBLivelistController alloc] init] andTitle:@"直播" andImage:[UIImage imageNamed:@"TabBar_LiveTab_normal"] selectImage:[UIImage imageNamed:@"TabBar_LiveTab_normal"]];
[self addChirdViewControllerWithClass:[[ZBVideoAlbumVC alloc] init] andTitle:@"首页" andImage:[UIImage imageNamed:@"TabBar_HomeTab_normal"] selectImage:[UIImage imageNamed:@"TabBar_HomeTab_normal"]];
[self addChirdViewControllerWithClass:[[ZBShortVideoVC alloc] init] andTitle:@"短视频" andImage:[UIImage imageNamed:@"TabBar_shortVideoTab_normal"] selectImage:[UIImage imageNamed:@"TabBar_shortVideoTab_normal"]];
}
- (void) addChirdViewControllerWithClass:(UIViewController *)vc andTitle:(NSString *)title andImage:(UIImage *)image selectImage:(UIImage *)selectImage
{
vc.title = title;
vc.tabBarItem.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
vc.tabBarItem.selectedImage = [selectImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
[self addChildViewController:nav];
}
@end
3. ZBLivelistController.m
#import "ZBLivelistController.h"
@interface ZBLivelistController ()
@end
@implementation ZBLivelistController
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tabBarController.tabBar.hidden = NO;
NSLog(@"ZBLivelistController --- viewWillAppear");
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.tabBarController.tabBar.hidden = YES;
NSLog(@"ZBLivelistController --- viewWillDisappear");
}
@end
4. ZBVideoAlbumVC.m
#import "ZBVideoAlbumVC.h"
@interface ZBVideoAlbumVC ()
@end
@implementation ZBVideoAlbumVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tabBarController.tabBar.hidden = NO;
NSLog(@"ZBVideoAlbumVC --- viewWillAppear");
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.tabBarController.tabBar.hidden = YES;
NSLog(@"ZBVideoAlbumVC --- viewWillDisappear");
}
@end
5. ZBShortVideoVC.m
#import "ZBShortVideoVC.h"
@interface ZBShortVideoVC ()
@end
@implementation ZBShortVideoVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tabBarController.tabBar.hidden = NO;
NSLog(@"ZBShortVideoVC --- viewWillAppear");
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.tabBarController.tabBar.hidden = YES;
NSLog(@"ZBShortVideoVC --- viewWillDisappear");
}
@end
运行起来如下图所示。
但是测试一下,我们就会发现,当点击短视频,再点击直播页面的时候,tabBar没有了,所以我们看打印输出。
2017-10-22 00:22:26.648393+0800 testDemo[6569:592943] ZBLivelistController --- viewWillAppear
2017-10-22 00:22:28.486030+0800 testDemo[6569:592943] ZBLivelistController --- viewWillDisappear
2017-10-22 00:22:28.504998+0800 testDemo[6569:592943] ZBShortVideoVC --- viewWillAppear
2017-10-22 00:22:30.118026+0800 testDemo[6569:592943] ZBLivelistController --- viewWillAppear
2017-10-22 00:22:30.119026+0800 testDemo[6569:592943] ZBShortVideoVC --- viewWillDisappear
这里就会发现,当我们点击短视频,在点击直播,就会发现,程序会先调用直播页面ZBLivelistController --- viewWillAppear
,而后调用短视频页面的ZBShortVideoVC --- viewWillDisappear
,这就导致了UITabBar被隐藏掉了,为什么会这样呢,和我们平时看到的控制器是不一样的,我们平时看到的都是先调用要消失控制器的willDisappear,后调用要出现的控制器视图的willAppear方法。在这里就是完全反的。这里我们怎么解决这个问题呢?
问题解决
有了上面的问题,我们就要解决,最简单直接的方法就是在三个子控制器中多加一个方法,如下所示。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.tabBarController.tabBar.hidden = NO;
}
这样就解决了生命周期的问题,解决隐藏时出现的错误。这样就可以在视图出现的时候就不要隐藏UITabBar,解决了这个问题。
后记
未完,待续~~~