视图控制器

⼀、⾃定义视图(label-textField组合视图 LTView)
⾃定义视图:系统标准UI之外,⾃⼰组合⽽出的新的视图。
⾃定义LTVie━使⽤了⼀种设计模式:复合设计模式。
复合设计模式:A类中,使⽤B类(或者更多类)作为⾃⼰的成员(实 例变量)。
iOS新控件往往都是⽤已有控件组 合⽽成的。
 
    1、新建一个空模板的工程,将环境配置为MRC,四步走
    2、新建一个视图控制器,将此视图控制器指定为window的根视图控制器
    3、自定义视图LTView,明确LTView内部的控件,声明为属性,重写initWithFrame:布局方法,先将子视图添加上去。完善显示效果,需要再去定义一个初始化方法,参数为视图的显示属性。
    4、自定义视图LoginView,明确内部的控件,声明为属性,重写initWithFrame:布局方法,添加子视图。
    5、视图控制器内部,重写loadView方法,指定视图控制器的空白视图为我们的自定义视图。(或者我们可以不建立自定义视图LoginView,在视图控制器的viewDidLoad方法里面,加载视图,完善视图控制器自带的空白视图)
    6、在视图控制器内部为输入框设置代理,为按钮添加事件
 
 不要忘了内存管理!!!
 
  • 代码实现:
创建一个UIView子类  @interface LTView : UIView
类的.h⽂件提供⼀些接⼝(⽅法),便于外界操作⼦视图。为了⽅便外界操作Label和TextField,因此我们要将这两个属性声明在.h ⽂件⾥。
//自定义视图第一步:明确该视图内部有什么控件,并且将所有控件声明成属性
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, retain) UITextField *textField;
 
//自定义初始化方法
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text textColor:(UIColor *)textColor font:(UIFont *)font borderStyle:(UITextBorderStyle)borderStyle placeholder:(NSString *)placeholder secureTextEntry:(BOOL)secureTextEntry keyboardType:(UIKeyboardType)keyboardType;
 
在.m中
//重写LTView继承自UIView的布局方法,来创建子视图,并且添加子视图
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        //用参数中的frame(LTView视图整体的frame)来表示内部控件的frame
        //LTView的宽和高
        CGFloat totalWidth = frame.size.width;
        CGFloat totalHeight = frame.size.height;
       
        //label的宽和高
        CGFloat labelWidth = (totalWidth - 15) / 3;
        CGFloat labelHeight = totalHeight - 4;
       
        //textField的宽和高
        CGFloat textFieldWidth = 2 * labelWidth;
        CGFloat textFieldHeight = labelHeight;
       
        _label = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, labelWidth, labelHeight)];
        [self addSubview:_label];
       
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(10 + labelWidth, 2, textFieldWidth, textFieldHeight)];
        [self addSubview:_textField];
    }
    return self;
}

//自定义初始化方法
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text textColor:(UIColor *)textColor font:(UIFont *)font borderStyle:(UITextBorderStyle)borderStyle placeholder:(NSString *)placeholder secureTextEntry:(BOOL)secureTextEntry keyboardType:(UIKeyboardType)keyboardType {
    self = [self initWithFrame:frame];
    if (self) {
        self.label.text = text;
        self.label.textColor = textColor;
        self.label.font = font;
        self.textField.borderStyle = borderStyle;
        self.textField.placeholder = placeholder;
        self.textField.secureTextEntry = secureTextEntry;
        self.textField.keyboardType = keyboardType;
    }
    return self;
}
 
AppDelegate.m
//创建承载视图,画纸
    UIView *containerView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    containerView.backgroundColor = [UIColor whiteColor];
    [self.window addSubview:containerView];
    [containerView release];
   
    CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
   
    //创建一个自定义视图LTView
    LTView *userNameLTV = [[LTView alloc] initWithFrame:CGRectMake(30, 80, screenWidth - 60, 40) text:@"用户名:" textColor:[UIColor blackColor] font:[UIFont boldSystemFontOfSize:18] borderStyle:UITextBorderStyleRoundedRect placeholder:@"请输入用户名" secureTextEntry:NO keyboardType:UIKeyboardTypeDefault];
    userNameLTV.textField.delegate = self;
    [containerView addSubview:userNameLTV];
    [userNameLTV release];
   
    LTView *passwordLTV = [[LTView alloc] initWithFrame:CGRectMake(30, 150, screenWidth - 60, 40) text:@"密  码:" textColor:[UIColor blackColor] font:[UIFont boldSystemFontOfSize:18] borderStyle:UITextBorderStyleRoundedRect placeholder:@"请输入密码" secureTextEntry:YES keyboardType:UIKeyboardTypeDefault];
    passwordLTV.textField.delegate = self;
    [containerView addSubview:passwordLTV];
    [passwordLTV release];
 
⼆、视图控制器
  • 视图控制器是应⽤程序数据和视图之间的重要桥梁,每个iOS应⽤程序 只显⽰⼀个⽤户界⾯,显⽰的内容是由控制器或⼀组视图控制器协调 管理。所以,视图控制器提供了⼀个基本的框架来构建应⽤程序。 
  • UIViewController是所有视图控制器的⽗类。
  • 功能:
     控制视图⼤⼩变换、布局视图、响应事件。 
     检测以及处理内存警告。
     检测以及处理屏幕旋转。
     检测视图的切换。
     实现模块独⽴,提⾼复⽤性
 
  • 试图控制器的使用:
定义UIViewController的⼦类:
@interface RootViewController : UIViewController
 
在APPDelegate⾥创建视图控制器对象,作为window的根视图控制器:
//创建一个视图控制器
    RootViewController *rootVC = [[RootViewController alloc] init];
   
    //将创建好的视图控制器指定为window的根视图控制器
    self.window.rootViewController = rootVC;
   
    //内存管理
    [rootVC release];
 
在viewDidLoad⽅法中使⽤默认创建好的视图对象view:
#pragma mark 视图加载完毕
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
     NSLog(@"%s %d", __FUNCTION__, __LINE__);
    // Do any additional setup after loading the view.
}
 
三、视图控制器指定视图
//加载根视图的方法,我们通常在这个方法中,指定根视图为我们想要的某个视图
//并且在一个视图控制器的生命周期,此方法只会走一次。
//在加载方法中,不能使用self.view这个getter方法获取根视图,因为此时根视图正在加载,并没有真实存在。
- (void)loadView {
    //创建loginView
    _loginView = [[LoginView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
   
    //将loginView指定为self.view
    self.view = _loginView;
//    [self.view addSubview:_loginView];
   
    //为输入框设置代理
    _loginView.userNameLTV.textField.delegate = self;
//    _loginView.passwordLTV.textField.delegate = self;
   
    //为button添加点击事件
    [_loginView.loginButton addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
}
 
四、MVC
UIViewController是MVC设计模式的核⼼。
MVC是⼀个框架级的设计模式。 
M是Model,主要⽤于建⽴数据模型(即数据的结构)。
V是View,我们能看到的所有控件都是view,view主要的功能是展⽰数据。 
C是控制器,主要是控制M和V的通信。
 
五、屏幕旋转
视图控制器本⾝能检测到屏幕的旋转,如果要处理屏幕旋转,需要重写⼏个 ⽅法: • supportedInterfaceOrientations (设置设备⽀持旋转的⽅向,如果不添加,视 图控制器将⽆法检测屏幕的旋转)。 
willRotateToInterfaceOrientation:duration:(暂停⾳乐、关闭视图交互等)。 willAnimateRotationToInterfaceOrientation:duration:(添加⾃定义动画 等)。 didRotateFromInterfaceOrientation:(播放⾳乐、打开视图交互等)。
 
//  GetPasswordView.m
//只要视图的bounds发生变化,就会触发视图本身的layoutSubviews方法
- (void)layoutSubviews {
    NSLog(@"%@",NSStringFromCGRect(self.bounds));
   
    //view重写layoutSubviews⽅法,根据设备⽅向,重新布局。
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
        self.findButton.frame = CGRectMake(300, 150, 200, 40);
    } else {
        self.findButton.frame = CGRectMake(100, 150, 200, 40);
    }
}
 
//  RootViewController.m
//旋转到某个方向
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self.getView.textField resignFirstResponder];
}

//旋转动画时执行的方法
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [self.getView.textField resignFirstResponder];
}
 
六、内存警告
如何处理:
控制器能监测内存警告,以便我们避免内存不够引起的crash。
在定义的controller⼦类中重写didReceiveMemoryWarning⽅法。
释放暂时不使⽤的资源(self.view及view的⼦视图例如数据对象、图 像)。
 
- (void)didReceiveMemoryWarning {
    //即使没有显⽰在window上,也不会⾃动的将self.view释放。
    [super didReceiveMemoryWarning];
     //根视图已经加载过,根视图未显⽰
    if ([self isViewLoaded] == YES && self.view.window == nil) {
        //将根视图销毁,⺫的是再次进⼊时能够重新加载调⽤viewDidLoad函数。
        self.view = nil;
    }
    NSLog(@"%s %d",__FUNCTION__, __LINE__);
   
    // Dispose of any resources that can be recreated.
}
原文地址:https://www.cnblogs.com/Walking-Jin/p/5210808.html