02_第七章_视图控制对象

本章主要讲解了UIViewController及其控制对象的视图之间的关系,视图的生命周期,和UITabBarController的基本用法,NSDate获取当前时间转换为字符串的方法。

demo讲解:

1.创建HypnoTime工程(本人习惯创建“空工程”),在appdelegate.m中创建一个UITabBarController.


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    
    //创建UITabBarController对象
    UITabBarController *tabBarController = [[UITabBarController alloc] init];
    
    //创建两个子视图控制对象实例
    UIViewController *vc1 = [[HypnosisViewController alloc] init];
    UIViewController *vc2 = [[CurrentTimeViewControoler alloc] init];
    
    //创建包含以上两个视图控制对象的数组对象
    NSArray *viewControllers = [NSArray arrayWithObjects:vc1, vc2, nil];
    
    //将新的视图对象加入UITabBarController对象
    [tabBarController setViewControllers:viewControllers];
    
    //将tabBarController设为window的rootViewController
    [self.window setRootViewController:tabBarController];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

其中的HypnosisViewController和CurrentTimeViewController会在下面讲到。UITabBarController的基本使用流程就是创建若干UIViewController实例,然后将其加到一组NSArray中。本例将UITabBarController设为程序的根视图控制对象。


2。创建HypnisisViewController和CurrentTimeViewController两个类。


HypnosisViewController.m

显示第六章中的同心圆和字符视图

- (id)init
{
    //调用父类的指定方法
    self = [super initWithNibName:nil bundle:nil];
    
    if (self) {
        //得到标签项
        UITabBarItem *tbi = [self tabBarItem];
        
        //为标签项设置标题
        [tbi setTitle:@"Hypnosis"];
        
        //通过文件创建UIImage对象
        UIImage *i = [UIImage imageNamed:@"Hypno.png"];
        
        //将该UIImage对象加入标签条项目
        [tbi setImage:i];
    }
    
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    //忽略参数——使用控制对象的内部默认实现来决定nib文件名
    return [self init];
}

//创建视图时,这个方法会被调用
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSLog(@"Loaded the view for HypnosisViewController");
    
    //设置视图的背景颜色以便查看
    //[self.view setBackgroundColor:[UIColor orangeColor]];
}

- (void)loadView
{
    HypnosisView *hv = [[HypnosisView alloc] initWithFrame:CGRectZero];
    [hv setBackgroundColor:[UIColor whiteColor]];
    [self setView:hv];
}



CurrentTimeViewController.m

用于显示当前时间

#define kTime @"What time is it?"

@implementation CurrentTimeViewControoler

- (id)init
{
    //调用父类的指定方法
    self = [super initWithNibName:nil bundle:nil];
    
    if (self) {
        //得到标签项
        UITabBarItem *tbi = [self tabBarItem];
        
        //为标签项设置标题
        [tbi setTitle:@"Time"];
        
        UIImage *i = [UIImage imageNamed:@"Time.png"];
        [tbi setImage:i];
    }
    
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    //忽略参数——使用控制对象的内部默认实现来决定nib文件名
    return [self init];
}

//创建视图时,这个方法会被调用
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSLog(@"Loaded the view for CurrentTimeViewController");
    
    //设置视图的背景颜色以便查看
    //[self.view setBackgroundColor:[UIColor greenColor]];
    
    timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 100, 200, 44)];
    timeLabel.textAlignment = NSTextAlignmentCenter;
    timeLabel.font = [UIFont boldSystemFontOfSize:18];
    
    timeBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    timeBtn.frame = CGRectMake(40, 200, 240, 44);
    timeBtn.titleLabel.font = [UIFont boldSystemFontOfSize:18];
    [timeBtn setTitle:kTime forState:UIControlStateNormal];
    [timeBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [timeBtn addTarget:self action:@selector(showCurrentTime:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:timeBtn];
    [self.view addSubview:timeLabel];
    
}

//刷新视图时更新时间
- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"CurrentTimeViewController will appear");
    [super viewWillAppear:animated];
    [self showCurrentTime:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    NSLog(@"CurrentTimeViewController will disappear");
    [super viewWillDisappear:animated];
}

- (void)showCurrentTime:(id)sender
{
    NSDate *now = [NSDate date];
    
    /*
     static意为“只创建一次”
     在应用首次载入内存时,会创建formatter变量
     第一次运行本方法时,formatter的值是nil
     所以会执行if语句块,创建NSDateFormatter对象,并将指针赋给formatter变量
     此后再执行这个方法,会重用之前创建的NSDateFormatter对象
     */
    static NSDateFormatter *formatter = nil;
    
    if (!formatter) {
        formatter = [[NSDateFormatter alloc] init];
        [formatter setTimeStyle:NSDateFormatterMediumStyle];
    }
    [timeLabel setText:[formatter stringFromDate:now]];
}

@end

覆盖UIViewController的init方法,在控制对象创建是设置其tabBarItem,注意tabBarItem的图像像素标准为30x30。

HypnosisView为第六章中的HypnosisView。


3.视图控制对象的生命周期与内存过低警告

(此处为个人的理解)UIVIewController的实例会在内存中一直存在,但其控制的视图(即self.view)会在内存过低时被回收掉。视图会在控制对象(即controller)第一次接收到view消息([self view]或self.view)时创建。view方法如下


- (UIView *)view
{
    if ([self isViewLoaded] == NO) {
        [self loadView];
        [self viewDidLoad];
    }
    return view;
}
可以看出,视图其实是通过loadView和viewDidLoad方法完成的。由此可见,我们不应该在controller的init方法中访问view(即发送view消息),否则内存过低时,该view无法被释放(上面讲的,controller一直存在在内存中)。

视图的生命周期(或者说各个方法的前后执行顺序为)

视图未存在时:

controller第一次接收到view消息 ----> view ----> loadView ----> viewDidLoad ----> viewWillAppear ----> viewDidAppear ----> viewWillDisappear ----> viewDidDisappear;

视图已存在时:

viewWillAppear ----> viewDidAppear ----> viewWillDisappear ----> viewDidDisappear;

当收到内存警告时,self.view = nil ----> viewDidUnload。


demo下载:https://github.com/ZiliKou/HypnoTime

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值