?、?定义视图(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.
}