iOS学习22之视图控制器

1.自定义视图

 1> 概述

    定义视图:系统标准UI之外,自己组合而出的新的视图。 

  定义视图的优点:

   iOS提供了很多UI组件,借助它们我们可以实现不同的功能。尽管如此,实际开发中,我们还需要自定义视图。积累自己的代码库,方便开发。自己封装的视图,能像系统UI控件一样,用于别的项目中,能大大降低开发成本,提高开发效率

   高质量代码的特点:可复用,可移植,精炼等。(高内聚,低耦合)

 2> 自定义视图步骤(以登录框为例(LTView))

  根据需求的不同,自定义视图继承的类也有所不同。一般自定义的视图会继承于UIView。以下是自定义视图的要点:

  ① 创建一个UIView子类: @interface LTView : UIView

  ② 在类的初始化方法中添加子视图

 1 // 添加视图
 2 - (void)addAllViews
 3 {
 4     // leftLabel
 5     self.leftLabel = [[UILabel alloc] initWithFrame:CGRectMake(kLabelX, kLabelY, 80, 30)];
 6     // 文本对齐
 7     self.leftLabel.textAlignment = NSTextAlignmentCenter;
 8     // 添加到自定义视图
 9     [self addSubview:self.leftLabel];
10     
11     
12     // rightTextField
13     self.rightTextField = [[UITextField alloc] initWithFrame:
14                            CGRectMake(CGRectGetMaxX(self.leftLabel.frame) + kSpace,
15                                       CGRectGetMinY(self.leftLabel.frame),
16                                       self.frame.size.width - CGRectGetWidth(self.leftLabel.frame) - kSpace - kLabelX * 2,
17                                       CGRectGetHeight(self.leftLabel.frame))];
18     // 设置边框样式
19     self.rightTextField.borderStyle = UITextBorderStyleRoundedRect;
20     // 添加到自定义视图
21     [self addSubview:self.rightTextField];
22 }

      ③ 类的.h文件提供一些接口(方法),便于外界操作子视图。

1 #import <UIKit/UIKit.h>
2 
3 @interface LTView : UIView
4 
5 // .h文件声明属性,为了方便和外界通信
6 @property (nonatomic, strong) UILabel *leftLabel;
7 @property (nonatomic, strong) UITextField *rightTextField;
8 
9 @end

      ④ 此时的 LTView 就变成了一个具有 labeltextField 的视图了。

 3> LTView在AppDelegate.m中的具体使用

 1     // 用户名
 2     LTView *userLTView = [[LTView alloc] initWithFrame:CGRectMake(10, 100, self.window.frame.size.width - 20, 50)];
 3     
 4     // 设置属性
 5     userLTView.backgroundColor = [UIColor lightGrayColor];
 6     userLTView.leftLabel.text = @"用户名";
 7     userLTView.leftLabel.backgroundColor = [UIColor redColor];
 8     userLTView.rightTextField.placeholder = @"请输入用户名";
 9     userLTView.rightTextField.backgroundColor = [UIColor redColor];
10     
11     // 设置代理
12     userLTView.rightTextField.delegate = self;
13     
14     // 添加父视图
15     [self.window addSubview:userLTView];
16     
17     // 密码
18     ZF_LTView *pwLTview = [[ZF_LTView alloc] initWithFrame:
19                            CGRectMake(CGRectGetMinX(userLTView.frame),
20                                       CGRectGetMaxY(userLTView.frame) + 20,
21                                       CGRectGetWidth(userLTView.frame),
22                                       CGRectGetHeight(userLTView.frame))];
23     
24     // 设置属性
25     pwLTview.backgroundColor = [UIColor lightGrayColor];
26     pwLTview.leftLabel.text = @"密码";
27     pwLTview.rightTextField.placeholder = @"请输入密码";
28     pwLTview.rightTextField.secureTextEntry = YES;
29     
30     // 添加到父视图
31     [self.window addSubview:pwLTview];

  效果图

2.视图控制器

 1> 概述

  视图控制器是应用程序数据视图之间的重要桥梁,每个iOS应用程序只显示一个用户界面,显示的内容是由控制器一组视图控制器协调管理。所以,视图控制器提供了一个基本的框架来构建应用程序。

  UIViewController所有视图控制器的父类

  iOS提供了许多内置的视图控制器,以支持标准的用户界面部分,比如导航控制器(UINavigationController),标签控制器 (UITabBarController), 表视图控制器(UITableViewController)等。

 2> 视图控制器的功能

  • 控制视图大小变换布局视图响应事件
  • 检测以及处理内存警告
  • 检测以及处理屏幕旋转
  • 检测视图的切换
  • 实现模块独立,提高复用性

 3> 视图控制器的使用

  ① 定义UIViewController的子类:

   @interface LoginViewController:UIViewController

    ② 在APPDelegate里创建视图控制器对象,作为window的根视图控制器:

1     // 创建window
2     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
3     self.window.backgroundColor = [UIColor redColor];
4     [self.window makeKeyAndVisible];
5     // 设置根视图控制器
6     self.window.rootViewController = [[LoginViewController alloc] init];

  ③ 在viewDidLoad方法中使用默认创建好的视图对象view:

1 #pragma mark 视图加载完毕
2 - (void)viewDidLoad {
3     [super viewDidLoad];
4     self.view.backgroundColor = [UIColor grayColor];
5     NSLog(@"%s  %d", __FUNCTION__, __LINE__);
6     // Do any additional setup after loading the view.
7 }

 4> 视图控制器生命周期

viewDidLoad --> viewWillAppear --> viewDidAppear --> viewWillDisappear --> viewDidDisappear

 1 @implementation ViewController
 2 
 3 // 视图已经加载
 4 - (void)viewDidLoad {
 5     [super viewDidLoad];
 6     // Do any additional setup after loading the view, typically from a nib.
 7     
 8     NSLog(@"1 %s__%d", __FUNCTION__, __LINE__);
 9 }
10 
11 // 视图将要出现
12 - (void)viewWillAppear:(BOOL)animated {
13     NSLog(@"2 %s__%d", __FUNCTION__, __LINE__);
14 }
15 // 视图将要消失
16 - (void)viewWillDisappear:(BOOL)animated {
17     NSLog(@"3 %s__%d", __FUNCTION__, __LINE__);
18 }
19 // 视图已经出现
20 - (void)viewDidAppear:(BOOL)animated {
21     NSLog(@"4 %s__%d", __FUNCTION__, __LINE__);
22 }
23 // 视图已经消失
24 - (void)viewDidDisappear:(BOOL)animated {
25     NSLog(@"5 %s__%d", __FUNCTION__, __LINE__);
26 }
27 
28 - (void)didReceiveMemoryWarning {
29     [super didReceiveMemoryWarning];
30     // Dispose of any resources that can be recreated.
31 }
32 
33 @end

3.视图控制器指示视图

 设置步骤

  自定义视图类继承UIView。在初始化方法添加子视图控件

 1 // 重写initWithFrame
 2 - (instancetype)initWithFrame:(CGRect)frame
 3 {
 4     self = [super initWithFrame:frame];
 5     if (self) {
 6         self.backgroundColor = [UIColor yellowColor];
 7         
 8         [self addAllViews];
 9     }
10     return self;
11 }
12 
13 // 添加视图
14 - (void)addAllViews
15 {
16     /**
17      *  布局: userLabel  userTextField  loginButton
18      *  事件: 代理事件   按钮点击事件   (controller实现)
19      *  @return nil
20      */
21     
22     // 布局userLabel
23     self.userLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, 60, 100, 40)];
24     self.userLabel.text = @"用户名";
25     self.userLabel.textAlignment = NSTextAlignmentCenter;
26     [self addSubview:self.userLabel];
27     
28     // 布局userTextField
29     self.userTextField = [[UITextField alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.userLabel.frame) + 20, CGRectGetMinY(self.userLabel.frame), 200, 40)];
30     self.userTextField.borderStyle = UITextBorderStyleRoundedRect;
31     self.userTextField.placeholder = @"请输入用户名";
32     [self addSubview:self.userTextField];
33     
34     // 布局loginButton
35     self.loginButton = [UIButton buttonWithType:UIButtonTypeSystem];
36     self.loginButton.backgroundColor = [UIColor cyanColor];
37     self.loginButton.frame = CGRectMake(50, CGRectGetMaxY(self.userTextField.frame) + kSpace, CGRectGetWidth(self.frame) - 100, 50);
38     [self.loginButton setTitle:@"登  录" forState:UIControlStateNormal];
39     
40     self.loginButton.tintColor = [UIColor whiteColor];
41     self.loginButton.layer.cornerRadius = 10;
42     
43     [self addSubview:self.loginButton];
44 }

  重写controllerloadView方法。创建自定义视图对象,并指定为controllerview。(注:loadView方法控制器viewnil的时候被调用,用于以编程的方式创建view的时候用到。loadView是使用代码生成视图的时候,当视图第一次载入的时候调用的方法,用于使用(写)代码来实现控件。)

 

 1 // 加载视图
 2 // 使用控制器指定自定义view(也就是替换控制器的view)
 3 // self.view没有被创建对象,节省内存
 4 - (void)loadView
 5 {
 6     // 初始化自定义视图
 7     self.loginView = [[LoginView alloc] initWithFrame:[UIScreen mainScreen].bounds];
 8     // 使用自定义视图替换控制器视图
 9     self.view = self.loginView;
10 }

  将子视图控件对象设置为自定义视图类的属性,在viewDidLoad方法中进行设置:添加action、设置delegate等等。

 1 // 处理事件一般都是在这个函数中实现
 2 - (void)viewDidLoad {
 3     [super viewDidLoad];
 4     // Do any additional setup after loading the view.
 5     
 6     // 处理事件
 7     
 8     // 1. 代理事件
 9     self.loginView.userTextField.delegate = self;
10     
11     // 2.按钮点击事件
12     [self.loginView.loginButton addTarget:self action:@selector(loginButtonClick) forControlEvents:UIControlEventTouchUpInside];
13 }

  在controller中添加按钮点击事件实现代理方法的实现。

 1 #pragma mark loginButtonClick Method (实现按钮点击方法)
 2 
 3 - (void)loginButtonClick
 4 {
 5     NSLog(@"别点我...");
 6     SecondViewController *secondVC = [[SecondViewController alloc] init];
 7     
 8     [self presentViewController:secondVC animated:YES completion:nil];
 9     
10 }
11 
12 #pragma mark UITextFieldDelegate Method (代理方法实现)
13 
14 // 点击return回收键盘
15 - (BOOL)textFieldShouldReturn:(UITextField *)textField
16 {
17     [textField resignFirstResponder];
18     return YES;
19 }
20 
21 // 触摸屏幕回收键盘
22 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
23 {
24     [self.view endEditing:YES];
25 }

4.MVC 

 1> 概述

 UIViewControllerMVC设计模式的核心。

 MVC是一个框架级的设计模式。

  MModel,主要用于建立数据模型(即数据的结构)。

  VView,我们能看到的所有控件都是view,view主要的功能是展示数据

  C是控制器,主要是控制M和V的通信。

 2> iOS中的MVC

5.屏幕旋转 

 1> 检测屏幕旋转

  视图控制器本身能检测到屏幕的旋转,如果要处理屏幕旋转,需要重写几个方法:

  supportedInterfaceOrientations(设置设备支持旋转的方向,如果不添加,视图控制器将无法检测屏幕的旋转)。

  willRotateToInterfaceOrientation:duration:(暂停音乐关闭视图交互等)。

  willAnimateRotationToInterfaceOrientation:duration:(添加自定义动画等)。

  didRotateFromInterfaceOrientation:(播放音乐打开视图交互等)。

1 #pragma mark 检测屏幕旋转
2 // 屏幕所支持的样式
3 - (UIInterfaceOrientationMask)supportedInterfaceOrientations
4 {
5     // 支持所有的方向
6     return UIInterfaceOrientationMaskAll;
7 }

 2> 视图处理

  注意视图控制器自动调整view的大小以适应屏幕旋转,bounds被修改,触发viewlayoutSubviews方法。

  view重写layoutSubviews方法,根据设备方向,重新布局。 

  [UIApplication sharedApplication].statusBarOrientation提供设备当前方向。

 1 // 布局子视图:当屏幕旋转的时候,可以重新布局子视图的位置
 2 - (void)layoutSubviews
 3 {
 4     // 如果是竖屏(UIInterfaceOrientationPortrait)的话,保持原来的尺寸
 5     if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
 6         self.loginButton.frame = CGRectMake(50, CGRectGetMaxY(self.userTextField.frame) + kSpace, CGRectGetWidth(self.frame) - 100, 50);
 7     } else { // 否则横屏改变位置
 8         self.loginButton.frame = CGRectMake(50, CGRectGetMaxY(self.userTextField.frame) + kSpace, 636, 50);
 9     }
10 }

6.内存警告 

 1> 概述

  内存警告来源:手机内存80M,程序运行过程中内存接近80M时程序会为每一个视图控制器发送内存警告消息。

  如何处理:

  ① 控制器能监测内存警告,以便我们避免内存不够引起的crash。

  ② 在定义的controller子类中重写didReceiveMemoryWarning方法。

  ③ 释放暂时不使用的资源(self.view及view的子视图例如数据对象、图 像)。

 2> 代码

1 // 当接收内存警告的时候都会走这个方法
2 - (void)didReceiveMemoryWarning {
3     [super didReceiveMemoryWarning];
4     // Dispose of any resources that can be recreated.
5     NSLog(@"%s__%d", __FUNCTION__, __LINE__);
6 }

 

posted @ 2016-04-08 17:06  墨隐于非  阅读(233)  评论(0编辑  收藏  举报