iOS UI学习之路04

来源:互联网 发布:巨人网络总部地址 编辑:程序博客网 时间:2024/06/05 20:32

UIViewController视图控制器

重要知识

视图控制器通常用来管理一个视图,其View属性指向它所管理的视图,这个视图通常被称为根视图

视图控制器并不能显示,具体显示的只是它所管理的视图

作用:创建管理视图;管理视图上显示的数据;设备方向变化,调整视图大小以适应屏幕;负责视图和模型之间的数据及请求的传递

子类:UINavigationController(导航控制器),UITabBarController(标签控制器)

视图控制器的创建

RootViewController *viewController = [[RootViewController alloc] init];

self.window.rootViewController = viewController;        //设置窗口的根视图

ViewController的生命周期及其加载View的步骤

ViewController的初始化:从Storyboards中加载的时候,会调用initWithCode,如果不存在则调用init。之后对里面的每个对象调用awakeFromNib方法。从内存中alloc出来的情况下,调init方法。

ViewController查找与其关联的view,其顺序是:

先判断子类是否重写了loadView,如果有直接调用。之后调viewDidLoad完成View的加载。

如果是外部通过调用initWithNibName:bundle指定nib文件名的话,ViewController记载此nib来创建View。

如果initWithNibName:bundle的name参数为nil,则ViewController会通过以下两个步骤找到与其关联的nib。

如果类名包含Controller,例如ViewController的类名是MyViewController,则查找是否存在MyView.nib;

找跟ViewController类名一样的文件,例如MyViewController,则查找是否存在MyViewController.nib。

如果子类没有重写的loadView,则ViewController会从StroyBoards中找或者调用其默认的loadView,默认的loadView返回一个空白的UIView对象。

注意第一步,ViewController是判断子类是否重写了loadView,而不是判断调用子类的loadView之后ViewController的View是否为空。就是说,如果子类重写了loadView的话,不管子类在loadView里面能否获取到View,ViewController都会直接调viewDidLoad完成View的加载。

ViewController的卸载View的步骤:

系统发出警告或者ViewController本身调用导致didReceiveMemoryWarning被调用

调用viewWillUnload之后释放View

调用viewDidUnload

视图控制器的生命周期

模态视图(视图控制器的切换)

模态视图作用:通常用于弹出临时的出窗口,如登录页面

模态视图原理:先将原先控制器的视图,从窗口移除,然后将第二个控制器的视图加到窗口上。

模态视图的弹出与销毁

//模态视图的弹出

//使用模态视图的方式,将vcRegist控制器的视图弹出,但self对象并未被销毁,只是将self的view从superView中//移除

RegisterViewController *vcRegist = [[RegisterViewController alloc] init];

self.modalTransitionStyle = UIModalTransitionStylePartialCurl;

[self presentViewController:vcRegist animated:YES completion:nil];

//模态视图的销毁,

//从superView中移除self.view,并且销毁self(视图控制器)对象,销毁后显示(原弹出self的view)的视图控制器//的视图

self.modalTransitionStyle = UIModalTransitionStylePartialCurl;

[self dismissViewControllerAnimated:YES completion:NULL];

导航控制器(UINavigationController)

介绍

有多个view时,可以用一个大的view却管理1个或者多个小view,控制器也是如此,用1个控制器去管理其他多个控制器

为了便于管理控制器,iOS提供了2个比较特殊的控制器。UINavigationController(导航控制器)与UITabBarController(标签控制器)

导航控制器属于容器类的控制器,可以管理很多子控制器,通常用它来控制自控制器之间的切换

导航控制器并不作显示,实际显示的是导航控制器所控制的自控制器的视图

特性

UINavigationController用于构建分层应用程序,管理多个视图换入和换出,自身提供视图切换动画效果。

UINavigationController继承自UIViewController

UINavigationController通过栈的方式管理控制器的切换,控制入栈和出栈,来展示各个视图控制器

导航控制器包含:NavigationBar(导航栏),内容视图

UINavigationController始终显示栈顶控制器的view

UINavigationController的viewControllers属性存储了栈中的所有被管理的控制器

被隐藏的工具栏

先设置nav.toolbarHidden = NO;后工具栏才会显示(nav为UINavigationController对象)

toolbarItems属性,可以为工具栏添加UIBarButtonItem类型的按钮

弹簧按钮

UIBarButtonSystemItemFlexibleSpace    将两边的元素(按钮)挤到最边上

UIBarButtonSystemItemFlexedSpace    空格站位按钮,可以设置宽度

子控制器的切换

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;//进入下一个视图控制器

- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated;//返回上一个视图控制器

- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;//返回到指定的视图控制器

- (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;//返回到根视图控制器

导航栏

特性

每个导航控制器只有一个导航栏(UINavigationBar)

导航控制器的每个子控制器都对应了一个导航项(UINavigationItem)

iOS7以后导航栏和状态栏发生了明显的变化,导航栏和状态栏变为了半透明,并且导航栏默认情况下与状态栏交织在一起。iOS7以前导航栏高度为44点,iOS7以后由于样式的改变高度变为64点

导航栏(UINavigationBar)父类:UIView

在UINavigationController类中有UINavigationBar类型的属性navigationBar

在下列代码中navCtrl为UINavigationController的对象

常用属性

@property(null_resettable, NOnatomic,strong) UIColor *tintColor;        //按钮字体颜色

@property(nullable, NOnatomic,strong) UIColor *barTintColor;        //设置导航栏背景颜色

@property(NOnatomic,assign) UIBarStyle barStyle;//导航栏样式。UIBarStyleBlack黑色半透明,会影响状态栏的颜色

@property(nullable,NOnatomic,weak) id<UINavigationBarDelegate> delegate;    //委托

@property(nullable,NOnatomic,copy) NSDictionary<NSString *,id> *titleTextAttributes;    //设置导航栏中标题的颜色

navCtrl.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]};

常用方法

- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics;//设置在UIBarMetrics状态下的背景图片

导航项

特征

在UINavigationController类中UINavigationItem类型的属性名:NavigationItem

导航项的归属关系

常用属性

title    自身ViewController的标题

titleView 自定义的view

prompt    二级标题

leftBarButtonItem、rightBarButtonItem、backBarButtonItem分别设置在导航栏上显示的左、右、返回按钮。类型为UIButtonItem    UIButtonItem父类:UIBarItem

self.navigationItem.leftBarButtonItem.customView.hidden = YES    隐藏左边按钮

设置导航栏上的按钮样式

系统提供的方式,只能设置左、右按钮

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem];

UIBarButtonSystemItemDone target:self action:@selector(test)];

self.navigationItem.leftBarButtonItem = item;

系统提供的方式,但增加了设置按钮标题,可设置左、右、返回按钮

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"Tens" style:[UIBarButtonItemStyleDone target:self action:@selector(test)];

self.navigationItem.leftBarButtonItem = item;

可设置按钮图片,只是保留了图片的形状,颜色被设置为系统颜色,可设置左、右、返回按钮

UIBarButtonItem *item = [[UIBarButton alloc] initWithImage:[UIImage imageNamed:@"test.png"] style:UIBarButtonItemStyleDone target:nil action:nil];

自定义按钮,只可设置左、右按钮

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

btn.frame = CGRectMake(0,0,30,30);

btn.setImage: [[UIImage imageNamed:@"test.png"] forState: UIControlStateNOrmal];

[btn addTarget: self action: @selector(totest:) forControlEvents: UIControlEventTochUpInSide];

UIBarButtonItem *btnBarRight = [[UIBarButtonItem alloc] initWithCustomView:btn];

self.navigationItem.rightBarButtonItem = btnBarRight;

标签控制器

特征

UITabBarController是UIViewController的子类

UITabBarController是用一种容器类的控制器,用于管理其他的子控制器

UITabBarController所管理的子控制器不同与导航控制器,UITabBarController的子控制器的平行关系

UITabBarController通常作为整个程序的rootViewController

标签控制器并不做显示,实际显示的是标签控制器所控制的子控制器的视图

使用步骤

初始化UITabBarController

创建若干个子控制器,放入到数组中

通过UITabBarController的ViewControllers属性将要显示的所有子控制器添加到UITabBarController中

将UITabBarController设置为窗口的根控制器

创建方式,ctrl1/ctrl2/ctrl3为UIViewController对象

UITabBarController *tabBar = [[UITabBarController alloc] init];

tabBar.viewControllers = @[ctrl1, ctrl2, ctrl3];

self.window.rootViewController = tabBar;

标签栏(UITabBar),父类:UIView

特征

UITabBarController会提供一个UITabBar(标签栏)

UITabBar的高度为49

当我们给UITabBarController设置子控制器后,系统会为我们自动在UITabBar上创建对应数量的UITabBarItem,用于子控制器的切换

iOS7以后UITabBar默认为半透明

UITabBarController只有一个TabBar(标签栏)

每个子控制器对应一个UITabBarItem,但标签栏上最多显示5个UITabBarItem,如果超过5个最后会以更多的形式显示

常用属性

tintColor    文字、图片的选中颜色

barTintColor    标签栏的背景颜色

backgroundImage    设置标签栏的背景图片

selectionIndicatorImage    设置选中的图片

标签栏元素(UIBarItem),标签栏元素属性名称:tabBarItem

常用属性

selectedImage    被选中后的图片

badgeValue    显示在图标右上角的文本

常用属性

initWithTitle: image: tag:     初始化标签栏元素标题、图标、tag值

initWithTitle: image: selectedImage:     初始化标签栏元素标题、图标、被选中的图标

经验

实现导航控制器push后,影藏TabBar;返回时,显示TabBar。背景:导航控制器是标签控制器的成员,标签控制器是根控制器。解决方案如下:

TabBar嵌套Navigation

self.hidesBottomBarWhenPushed = YES;    设置隐藏时,设置当前及push后的vc隐藏,但已在当前不应藏,以后会隐藏

HomeVC2 *vcHome2 = [[HomeVC2 alloc] init];

[self.navigationController pushViewController: vcHome2 animated:YES];

self.hide.BottomBarWhenPushed = NO;    当设置显示,谁去设置谁才显示,只能设置自己显示

设置TabBarController的TabBar

在tochesBegan事件处理方法中:self.navigationController.tabBarController.tabBar.hidden = YES;

在viewWillAppear事件处理方法中:self.navigationController.tabBarController.tabBar.hidden = NO;

同①相似

HomeVC2 *vcHome2 = [[HomeVC2 alloc] init];

vcHome2.hidesBottomBarWhenPushed = YES;

设置vcHome2 控制器及push以后的标签栏隐藏

[self.navigationController pushViewController:vcHome2 animated:YES];