UITextField控件
UITextFiled常用属性和方法
UITextField是常用的文本输入控件,比如我们用的QQ的登录界面,词典输入要查询的单词都使用了文本框控件,如下图所示。之前介绍的UILabel可以在界面中显示文本,但用户无法选择或编辑UILabel中的文本,想接受用户输入文本,就可以使用UITextField控件。当我们在用户界面上点击文本框时,屏幕底部会弹出键盘,用于向文本框中输入文字。
************************************************************************************************************************************************************************************************************************
1、创建UITextField
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(20, 40, self.view.frame.size.width - 40 , 50)];
2、设计边框的样式
边框样式(UITextBorderStyleNone, UITextBorderStyleBezel, UITextBorderStyleLine, UITextBorderStyleRoundedRect)
textField.borderStyle = UITextBorderStyleRoundedRect;
3、背景图
[tf setBackground:[UIImage imageNamed:@"bg"]];
enabled属性:是否可编辑
tf.enabled = NO;设置不可以编辑时的图片
4、背景色
tf.backgroundColor = [UIColor whiteColor];
- 5、设置占位符
- textField.placeholder = @"请输入用户名";
- 6、设置字体
- 设置字体大小
- textField.font = [UIFont systemFontOfSize:30];
- 根据文本的多少和文本输入宽度调整字体大小
- textField.adjustsFontSizeToFitWidth = YES;
- 最小字体
- textField.minimumFontSize = 20;
- 文字颜色
- tf.textColor = [UIColor whiteColor];
- 7、对齐方式
- //水平对齐样式
- // UIControlContentHorizontalAlignmentCenter = 0,
- // UIControlContentHorizontalAlignmentLeft = 1,
- // UIControlContentHorizontalAlignmentRight = 2,
- // UIControlContentHorizontalAlignmentFill = 3,
- //垂直对齐
- // UIControlContentVerticalAlignmentCenter = 0,
- // UIControlContentVerticalAlignmentTop = 1,
- // UIControlContentVerticalAlignmentBottom = 2,
- // UIControlContentVerticalAlignmentFill = 3,
textField.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
8、是否使用掩码
textField.secureTextEntry = YES;
9、左视图(可以定制文本框)/ 左视图模式
右视图(可以定制文本框,可能会覆盖掉清除文字的按钮)/ 右视图模式
// UITextFieldViewModeNever,
// UITextFieldViewModeWhileEditing,
// UITextFieldViewModeUnlessEditing,
// UITextFieldViewModeAlways
tf.leftViewMode = UITextFieldViewModeAlways;
tf.leftView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"qq"]];
10、inputView / inputAccessoryView属性:输入/辅助视图(可以完成键盘的定制,可以在原始的键盘上设置二级键盘)
11、 //结束编辑,隐藏键盘
[self.view endEditing:YES];
如何定制键盘
- keyBoardAppearance属性:键盘的外观(四种外观,分别是:UIKeyboardAppearanceDefault、UIKeyboardAppearanceLight、UIKeyboardAppearanceDark、UIKeyboardAppearanceAlert)
- keyBoardType属性:键盘的类型,包括:UIKeyboardTypeAlphabet、UIKeyboardTypeASCIICapable、UIKeyboardTypeDecimalPad、UIKeyboardTypeDefault、UIKeyboardTypeEmailAddress、UIKeyboardTypeNamePhonePad、UIKeyboardTypeNumberPad、UIKeyboardTypeNumbersAndPunctuation、UIKeyboardTypePhonePad,默认键盘可以输入其他键盘输入的内容
- returnKeyType属性:返回键的类型,包括:UIReturnKeyDefault、UIReturnKeyDone、UIReturnKeyEmergencyCall、UIReturnKeyGo、UIReturnKeyGoogle、UIReturnKeyJoin、UIReturnKeyNext、UIReturnKeyRoute
第一响应者
UIResponder是UIKit框架中的一个抽象类,UIView、UIViewController、UIApplication都是它的子类。UIResponder定义了一系列方法,用于接收和处理用户事件,例如触摸事件、运动事件(摇晃手机)和功能控制事件(编辑文本或播放音乐)等。以上事件中,触摸事件显然应该由被触摸的视图负责处理,系统将触摸事件直接发送给被触摸的视图。其他类型的事件则会由第一响应者(first responder)负责处理,UIWindow有一个firstResponder属性指向第一响应者。如果希望启动应用程序时文本框直接获得焦点显示输入键盘,或者希望点击屏幕其他区域输入键盘消失可以通过下面的方法来设置第一响应者来实现。
- //使他成为第一响应者
- [textField becomeFirstResponder];
- //取消第一响应者
- [textField resignFirstResponder];
UITextField常用代理方法
在之前的OC课程中,我们了学习过一个非常重要的概念叫协议(相当于Java和C#中的接口),它是实现委托回调的关键,如果一个类遵守这个协议,那么它拥有协议中规定的方法,我们就可以将它的对象设置为被委托放,来帮助委托方完成某些功能。如果一个类遵循UITextFieldDelegate协议,它的对象就可以作为被委托方帮我们处理文本框(委托方)编辑时引发的事件。
- delegate属性
UITextFieldDelegate协议的源代码:
@protocol UITextFieldDelegate <NSObject>
@optional
// 可以通过返回NO阻止编辑
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
// 当文本框成为第一响应者时执行此方法
- (void)textFieldDidBeginEditing:(UITextField *)textField;
// 返回YES来允许结束编辑
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;
// 当文本框放弃第一响应者时执行此方法
- (void)textFieldEndEndEditing:(UITextField *)textField;
// 返回NO可以阻止对文本框内容的修改(用于定制文本框输入内容)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
// 清除文本框中的文本时执行
- (BOOL)textFieldShouldClear:(UITextField *)textField;
// 输入结束返回时执行
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
@end
&
UIViewController视图控制器
创建视图控制器
视图控制器是UIViewController类或其子类对象,每个视图控制器都负责管理一个视图层次结构,包含创建视图层次结构中的视图并处理相关用户事件,以及将整个视图层次结构添加到应用窗口。
MVC架构模式:模型-视图-控制器,UIViewController就是MVC模式中的C。
视图控制器的生命周期
我们先通过代码看看和视图控制器生命周期相关的方法。
- (void)viewDidLoad {
[super viewDidLoad];
// 当控制器管理的视图被装载完成后,调用该方法,
}
- (void)viewWillAppear:(BOOL)animated {
// 当该控制器管理的视图将要显示出来时,系统会自动的调用该方法,
}
- (void)viewDidAppear:(BOOL)animated {
// 当该控制器管理的视图显示出来时,系统会自动的调用该方法
}
- (void)viewWillDisappear:(BOOL)animated {
// 当该控制器管理的视图将要隐藏或将要被移除窗口时,系统会自动的调用该方法
}
-(void)viewDidDisappear:(BOOL)animated {
// 当该控制器管理的视图被隐藏或移除窗口时,系统会自动的调用该方法
}
-(void)viewDidLayoutSubviews {
// 当该控制器管理的视图把它包含的所有子视图排列完成后,系统会自动的调用该方法
}
-(void)viewWillLayoutSubviews {
// 当该控制器管理的视图将要把它包含的所有子视图排列完成后,系统会自动的调用该方法
}
- (void)didReceiveMemoryWarning {
// 内存不足时调用的方法,开发者可在需要时释放一些暂不会使用的对象,进而释放内存
}
说明:loadView和viewDidLoad的区别就是,loadView执行时view还没有生成,viewDidLoad时,view已经生成了,loadView和viewDidLoad通常只会被调用一次,而其他方法可能会被调用多次,当view被添加到其他view中之前,会调用viewWillAppear,之后会调用viewDidAppear。当view从其他view中移除之前,调用viewWillDisAppear,移除之后会调用viewDidDisappear。当view不再使用或受到内存警告时,ViewController可能会将view释放并将其指向为nil。图中的viewDidUnload方法在iOS 6中已经过时,可以在下面的方法中处理收到内存警告时要做的事情。
内存告急时会发生什么
回调UIViewController对象的didReceiveMemoryWarning方法。
UIViewController的视图切换
- 通过模态化的方式切换视图
- -presentViewController:animated:completion:方法:显示模态视图控制器
- -dismissViewControllerAnimated:completion:方法:撤回模态视图控制器
- //弹出模态视图 self presentViewController
- //模态视图消失 self dismissViewController
- //这两个方法是成双成对
- SecondViewController *vc = [[SecondViewController alloc]init];
- //第一个参数 使我们要进入的UIViewController对象
- //第二个参数 是动画效果
- //第三个参数 block
- [self presentViewController:vc animated:YES completion:^{
- NSLog(@"按钮动作结束");
- 直接切换视图
- 通过UIView的wind ow属性获得UIWindow对象
- 重新指定UIWindow对象的rootViewController属性
- //创建一个窗口对象,并设置坐标和大小
- self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
- //根视图 UIViewController ,我们的视图可能有很多界面,每个界面就是一个UIViewController
- self.window.rootViewController = [[TextViewController alloc]init];
- //3 添加
- [self.window makeKeyAndVisible];
视图控制器之间传值
1. 及时性传值
(1) 委托传值:提供数据(状态)的视图控制器(称为B)通过委托回调需要数据(状态)的视图控制器(称为A)中的方法。A作为被委托方需要遵循协议,B作为委托方需要一个指向遵循协议的对象的指针,当通过A启动B时,将该指针赋值为self,即由A充当B的委托,B在需要反向传值时通过该指针回调A提供的方法(协议中定义的由A实现的方法)。
(2) Block传值:需要数据的视图控制器(称为A)通过Block将一段代码传入提供数据的视图控制器(称为B)中,当B需要反向传值时回调A传入的代码。
A中创建Block并赋值给B中的Block类型的属性
- (void) okButtonClicked {
// 创建一个Block类型的变量
void (^fn)(UISwitch *) = ^(UISwitch * bt) {
UIButton *okButton = (id)[self.view viewWithTag:101];
[okButton setTitle:(bt.isOn? @"关闭蓝牙":@"打开蓝牙") forState:UIControlStateNormal];
self.flag = bt.isOn;
};
CDModalViewController *modalVC = [[CDModalViewController alloc]init];
modalVC.block = fn; // 为B设置Block属性
[self presentViewController:modalVC animated:YES completion:nil];
}
B需要向A反向传值时调用调用此Block
- (void) switchValueChanged:(UISwitch *)bt {
if (self.block) {
self.block(bt);
}
}
(3) 通知传值:需要数据的视图控制器(称为A)注册一个观察者,提供数据的视图控制器(称为B)向观察者发送通知完成反向传值,这是对观察者模式的应用。
A通过消息中心注册观察者
- (void)viewDidLoad {
[super viewDidLoad];
// A通过通知中心注册一个观察者
// 第一个参数是A自身,第二个参数是收到通知的回调方法
// 第三个参数是通知的名称,与通知发送方设置的通知名称一致
// 第四个参数是接受哪个对象发送的通知,如果为nil则不管哪个对象发送通知都接受
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showSwitchStatus:) name:@"SwitchValueChanged" object:nil];
}
// 收到通知后的回调方法
- (void) showSwitchStatus:(NSNotification *) not {
UIButton *okButton = (id)[self.view viewWithTag:101];
UISwitch *currentSwitch = not.object;
self.flag = currentSwitch.isOn;
[okButton setTitle:(self.flag? @"关闭蓝牙":@"打开蓝牙") forState:UIControlStateNormal];
}
在事件发生时向观察者发出通知
- (void) switchValueChanged:(UISwitch *)bt {
// B创建通知对象,其中第一个参数是通知的名称,
// 第二个参数是和通知绑定的对象
NSNotification *note = [[NSNotification alloc] initWithName:@"SwitchValueChanged" object:bt userInfo:nil];
// B发送通知
[[NSNotificationCenter defaultCenter] postNotification:note];
}
2. 非及时性传值
AppDelegate传值
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, copy) NSString *myText;
@end
AppDelegate *appDel = [UIApplication sharedApplication].delegate;
// 获得AppDelegate对象后就可以操作myText属性完成赋值或取值操作
// 由于这种传值方式属于非及时性传值需要通过代码完成对视图的刷新