【iOS开发-30】UITabBarController的几种代理方法以及结合NSUserDefaults还原上次退出时被选中视图控制器和视图控制器的顺序

一、UITabBarController的几种代理方法

在AppDelegate.h中加入一个协议<UITabBarControllerDelegate>,然后再AppDelegate.m中添加如下代理方法:

如果没有效果,可能是缺少tbCon1.delegate=self;把代理指定给当前AppDelegate。

-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
    NSLog(@"clicked");
    return YES;
}

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{

    NSLog(@"%@",viewController.title);
}

-(void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers{
    NSLog(@"will Customize");
}

-(void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed{
    if (changed) {
        NSLog(@"changed!");
    }else{
        NSLog(@"not changed");
    }
    for (UIViewController *vcs in viewControllers) {
        NSLog(@"%@",vcs.title);
    }
}

-(void)tabBarController:(UITabBarController *)tabBarController DidEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed{

}

二、注意事项

(1)用代理方法调用title时,只有当上面的视图控制器或者导航控制器用.title方法赋值,才能被调用。否则返回值是Null。

(2)而用initWithTitle方法赋值的都是给.tabBarItem.title赋值,无法直接用.title来获取到值。

(3)所以,如果有用initWithTitle赋值的,可以再用.title重新赋值一遍,这样便于在其他方法中获取到值。

三、利用NSUserDefaults复原上次被选中视图

在didSelectViewController代理方法中创建一个NSUserDefaults来记录被选中的那个视图的title。

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
    //选择某一个视图控制器后,就把对应的标题存储在NSUserDefaults中,在上面利用
    //创建一个NSUserDefaults,如果能取到title,就把title赋值进去储存
    NSUserDefaults *def1=[NSUserDefaults standardUserDefaults];
    if (viewController.title) {
        [def1 setObject:viewController.title forKey:SELECTEDKEY];
    }
    //数据同步到应用程序中
    [def1 synchronize];
}

然后,在didFinishLaunchingWithOptions方法中加入以下代码,即如果查到上次退出程序时有存储title的话,那么就寻找这个title对应的视图控制器,并把这个视图控制器设置为我们本次打开程序默认的选中视图控制器,如此便相当于还原了上次选中的模样。(SELECTEDKEY是#define的宏变量)

//如果NSUserDefaults里面有存储的,就直接取值过来,然后与现有的标签比较,就可以得知上次打开的时哪一个标签,并把这个把标签设置为默认打开的
    if ([[NSUserDefaults standardUserDefaults]objectForKey:SELECTEDKEY]) {
        for (UIViewController *vcs1 in arr2) {
            if ([vcs1.title isEqualToString:[[NSUserDefaults standardUserDefaults]objectForKey:SELECTEDKEY]]) {
                tbCon1.selectedViewController=vcs1;
            }
        }
    }

四、利用NSUserDefaults复原上次视图顺序

在didEndCustomizingViewControllers代理方法中创建一个NSUserDefaults来记录上次视图控制器的顺序,当然是记录它们的标题顺序。

-(void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed{
    //把点击DONE之后的新的视图控制器的标题按顺序存在def2中,然后在上面利用
    NSUserDefaults *def2=[NSUserDefaults standardUserDefaults];
    NSMutableArray *arr2=[[NSMutableArray alloc]init];
    for (UIViewController *vcs2 in viewControllers) {
        [arr2 addObject:vcs2.title];
    }
    [def2 setObject:arr2 forKey:TITLESKEY];
    [def2 synchronize];
}

然后,在didFinishLaunchingWithOptions方法中加入以下代码,即如果我们捕捉到之前有存储的title数组,那么从第一个title开始找它对应的视图控制器,并把这个视图控制器存放在新的数组里面,这样按顺序就可以得到一个新的顺序的视图控制器数组。最后把这个新的视图控制器数组赋值给标签控制器的viewControllers,就相当于还原了上次退出程序时视图控制器顺序的模样。(TITLESKEY是#define的一个宏变量)

    //使用之前关闭程序前标签栏的顺序
    //创建一个数组,把存储在NSUserDefaults里地数组取出来
    NSArray *newTitle1=[[NSUserDefaults standardUserDefaults]objectForKey:TITLESKEY];
    //如果确实有这个数组,那么遍历这个标题数组和之前的视图控制器数组,如果视图控制器的标题等于这个数组的第一个标题,那么就把这个视图控制器放在一个新的数组里面
    if (newTitle1) {
        NSMutableArray *newArr1=[[NSMutableArray alloc]init];
        for (NSString *title1 in newTitle1) {
            for (UIViewController *vcs3 in arr2) {
                if ([vcs3.title isEqualToString:title1]) {
                    [newArr1 addObject:vcs3];
                }
            }
        }
        //然后把这个新的视图控制器的数组赋值给标签控制器
        tbCon1.viewControllers=newArr1;
    }

五、关于NSUserDefaults的更多阅读

(1)NSUserDefaults注意事项

(2)NSUserDefaults简介及使用

(3)NSUserDefaults详解

时间: 2024-08-01 10:42:34

【iOS开发-30】UITabBarController的几种代理方法以及结合NSUserDefaults还原上次退出时被选中视图控制器和视图控制器的顺序的相关文章

iOS开发CoreAnimation解读之三——几种常用Layer的使用解析

iOS开发CoreAnimation解读之三——几种常用Layer的使用解析 一.CAEmitterLayer 二.CAGradientLayer 三.CAReplicatorLayer 四.CAShapeLayer 五.CATextLayer iOS开发CoreAnimation解读之三——几种常用Layer的使用解析 一.CAEmitterLayer CAEmitterLayer是CoreAnimation框架中的粒子发射层,在以前的一片博客中有详细的介绍和范例,这里不再重复,地址如下: 粒

IOS开发隐藏键盘的4种方法

IOS开发隐藏键盘的4种方法 开发的app中常会用到键盘输入完成后隐藏键盘的情况.在此总结了4种方法来实现我们的目的. 方法一--delegate方式 第一种隐藏键盘的方法,称为delegate三步法: 1. 遵循(委托/代理); 2. 调用; 3. 关联头文件(ViewController.h)中遵循代理 . 代码如下: #import <UIKit/UIKit.h> @interface ViewController : UIViewController<UITextFieldDel

iOS开发中单例对象的标准创建方法

//标准的单例写法 //以创建歌曲的管理者为例进行创建.+(instancetype) sharedQYSongManager { static QYSongsManager *songManager =nil; //采用GDC标准单例实现方法 static dispatch_once_t onceToken; //Executes a block object once and only once for the lifetime of an application. dispatch_onc

iOS开发-No matching provisioning profiles found解决方法

今天真机调试的时候莫名其妙遇到了这样的一个问题: This product type must be built using a provisioning profile, however no provisioning profile matching both the identity "iPhone Developer" and the bundle identifier..... 具体如下图所示: 十分蛋疼, 发现不管是从网上下的demo, 还是自己的过程.凡事真机测试的时候都

iOS开发——动画编程的几种方法

动画编程的几种方法 IOS中的动画总结来说有五种:UIView<block>,CAAnimation<CABasicAnimation,CATransition,CAKeyframeAnimation>,NSTimer 这里我就总结了一下这五种方法,其实iOS开发中动画的编程都会在这里面变化,所以只要弄懂了这些动画编程就不难了. 一:UIView动画 一般方式 [UIView beginAnimations:@"ddd" context:nil];//设置动画[

iOS开发中常用的几种设计模式

下面是iOS开发中比较常用的几种设计模式.详情如下所示: (一)代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现.优势:解耦合敏捷原则:开放-封闭原则实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求.列表row个数delegate自定义的delegate (二)观察者模式应用场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,只负责发布信息.优势:解耦合敏捷原则:接口隔离原

iOS开发总结之UITextField常用属性和方法

UITextField属性 0.        enablesReturnKeyAutomatically 默认为No,如果设置为Yes,文本框中没有输入任何字符的话,右下角的返回按钮是disabled的. 1.borderStyle 设置边框样式,只有设置了才会显示边框样式 text.borderStyle =UITextBorderStyleRoundedRect; typedef enum { UITextBorderStyleNone, UITextBorderStyleLine, UI

android开发中监听器的三种实现方法(OnClickListener)

Android开发中监听器的实现有三种方法,对于初学者来说,能够很好地理解这三种方法,将能更好地增进自己对android中监听器的理解. 一.什么是监听器. 监听器是一个存在于View类下的接口,一般以On******Llistener命名,实现该接口需要复写相应的on****(View v)方法(如onClick(View v)). 二.监听器的三种实现方法 (以OnClickListener为例) 方法一:在Activity中定义一个内部类继承监听器接口(这里是OnClickListener

ios开发runtime学习二:runtime交换方法

#import "ViewController.h" /* Runtime(交换方法):主要想修改系统的方法实现 需求: 比如说有一个项目,已经开发了2年,忽然项目负责人添加一个功能,每次UIImage加载图片,告诉我是否加载成功 当系统提供的控件不能满足我们的需求的时候,我们可以 1:通过继承系统控件,重写系统的方法,来扩充子类的行为(super的调用三种情况) 2:当需要为系统类扩充别的属性或是方法的时候,与哪个类有关系,就为哪个类创建分类.3:利用runtime修改系统的类,增加