iOS开发_7_UITextField

UIResponder

UIResponder是UIkit框架中的一个抽象类,其定义了一系列方法,用于接收和处理用户事件,例如触摸事件、运动事件(摇晃设备)和功能控制事件(编辑文本或播放音乐)等。UIResponder的子类会覆盖这些方法。

UIWindow有一个firstResponder属性指向第一响应者。例如,当用户点击UITextField对象时,UITextfield对象就会成为第一响应者。UIWindow会将firstResponder指向该对象,之后,如果应用接收到运动事件和功能控制事件,都会发送给UITextField对象。

当某个UITextField对象或者UITextView对象成为第一响应者时,屏幕会弹出键盘。除了用户点击外,还可以在代码中向UITextField对象发送becomeFirstResponser消息,使其成为第一响应者。如果要关闭键盘,则可以向UITextField对象发送resignFirstResponder消息。

设置UITextField的键盘

UITextField的几个属性

  • autocapitalizationType:设置UITextField对象的自动大写功能,包括none、words(单词)、sentence、allcharacter(所有字母)

  • autocorrectionType:启用/禁用(设置为YES/NO,下同)UITextField对象的拼写建议功能

  • enablesReturnKeyAutomatically:启用/禁用UITextField对象的换行键自动检测功能,如果将该属性设置为YES,UITextField对象会自动检测用户输入,并根据是否输入文字启用/禁用换行键

  • keyboardType:设置UITextField对象弹出键盘类型,例如ASCII Capble(ASCII标准键盘)、E-Mail Address(电子邮件地址)、Number pad(数字键盘)和URL(网址)

  • secureTextEntry:启用/禁用UITextField对象的安全输入功能,如果将该属性设置为YES、UITextField对象会以原点代替用户输入的文字,常见于密码输入框

委托

UITextField对象具有一个委托属性,通过UITextField对象设置委托,UiTextField对象会在发生事件时向委托发送相应的消息,由委托处理该事件。

对于编辑UiTextField对象文本内容的事件,有以下两个对应的委托方法:

-(void) textFieldDidEndEditing: (UITextField *) textField;

-(void) textFieldDidBeginEditing: (UITextField *) textField;

还有带返回值的委托方法,用于从委托中查询需要的信息

-(void) textFieldShouldEndEditing: (UITextField *) textField;

-(void) textFieldShouldBeginEditing: (UITextField *) textField;

-(void) textFieldShouldClear: (UITextField *) textField;

-(void) textFieldShouldReturn: (UITextField *) textField;

注意,在委托方法中,通常应该将对象自身作为第一个参数。

多个对象可能具有相同的委托,当委托收到消息时,需要根据该参数判断发送给该消息的对象。例如,某个控制器中包含多个UITextField对象,他们的委托都是该控制器,那么控制器要根据TextField参数获取相应的UITextField对象并执行不同操作。

协议

凡是支持委托的对象,其背后都有一个相应的协议,声明可以向该对象的委托对象发送的消息。被委托对象需要根据这个协议为其“感兴趣”的事件实现相应的方法。如果一个类实现了某个协议中规定的方法,称这个类遵守协议。

UITextField的协议:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@protocol UITextFieldDelegate <NSObject>

@optional

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; // return NO to disallow editing.
- (void)textFieldDidBeginEditing:(UITextField *)textField; // became first responder
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField; // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
- (void)textFieldDidEndEditing:(UITextField *)textField; // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason NS_AVAILABLE_IOS(10_0); // if implemented, called in place of textFieldDidEndEditing:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text

- (BOOL)textFieldShouldClear:(UITextField *)textField; // called when clear button pressed. return NO to ignore (no notifications)
- (BOOL)textFieldShouldReturn:(UITextField *)textField; // called when 'return' key pressed. return NO to ignore.

@end

发送方在发送可选方法前,会先向其委托发送另一个名为respondsToSelector:方法。

所有objective-c对象都从NSObject继承了respondToSelector:方法,该方法能在运行时检查对象是否实现了指定的方法。

@selector()指令可以将选择器(selector)转换成数值,以便将其作为参数进行传递。

例如,UITextField可以实现如下方法

1
2
3
4
5
6
7
8
9
10
- (void)clearButtonTapped
{
//textFieldshouldClear:是可选方法,需要检查委托是否实现了该方法
SEL clearAelector = @selector(textFieldShouldClear);
if([self.delegate respondsToSelector:clearSelector]){
if([self.delegate textFieldShouldClear:self]){
self.text = @"";
}
}
}

iOS SDK很多类都具有委托,几乎所有的委托都是弱引用(weak);这是为了避免对象及其委托之间产生强引用循环。

向屏幕中添加UILabel对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
- (void)drawHypnoticMessage:(NSString *)message
{
for (int i = 0; i < 20; i++) {
UILabel *messageLabel = [[UILabel alloc] init];

// Configure the label's colors and text
messageLabel.backgroundColor = [UIColor clearColor];
messageLabel.textColor = [UIColor whiteColor];
messageLabel.text = message;

// This method resizes the label, which will be relative
// to the text that it is displaying
[messageLabel sizeToFit];

// Get a random x value that fits within the hypnosis view's width
int width = self.view.bounds.size.width - messageLabel.bounds.size.width;
int x = arc4random_uniform(width);

// Get a random y value that fits within the hypnosis view's height
int height = self.view.bounds.size.height - messageLabel.bounds.size.height;
int y = arc4random_uniform(height);

// Update the label's frame
CGRect frame = messageLabel.frame;
frame.origin = CGPointMake(x, y);
messageLabel.frame = frame;

// Add the label to the hierarchy
[self.view addSubview:messageLabel];
//添加视差效果
UIInterpolatingMotionEffect *motionEffect;
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = @-25;
motionEffect.maximumRelativeValue = @25;
[messageLabel addMotionEffect:motionEffect];

motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
motionEffect.minimumRelativeValue = @-25;
motionEffect.maximumRelativeValue = @25;
[messageLabel addMotionEffect:motionEffect];
}
}

附:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//  BNRHypnosisViewController.m

#import "BNRHypnosisViewController.h"
#import "BNRHypnosisView.h"

@interface BNRHypnosisViewController () <UITextFieldDelegate>

@end

@implementation BNRHypnosisViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {

// Set the tab bar item's title
self.tabBarItem.title = @"Hypnotize";

// Create a UIImage from a file
// This will use Hypno@2x on retina display devices
UIImage *image = [UIImage imageNamed:@"Hypno.png"];

// Put that image on the tab bar item
self.tabBarItem.image = image;
}

return self;
}

- (void)loadView
{
// Create a view
CGRect frame = [UIScreen mainScreen].bounds;
BNRHypnosisView *backgroundView = [[BNRHypnosisView alloc] initWithFrame:frame];

CGRect textFieldRect = CGRectMake(40, 70, 240, 30);
UITextField *textField = [[UITextField alloc] initWithFrame:textFieldRect];

// Setting the border style on the text field will allow us to see it easier
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"Hypnotize me";
textField.returnKeyType = UIReturnKeyDone;
[backgroundView addSubview:textField];

textField.delegate = self;

// Set it as *the* view of this view controller
self.view = backgroundView;
}

- (void)viewDidLoad
{
// Always call the super implementation of viewDidLoad
[super viewDidLoad];

NSLog(@"BNRHypnosisViewController loaded its view");
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self drawHypnoticMessage:textField.text];

textField.text = @"";
[textField resignFirstResponder];

return YES;
}

- (void)drawHypnoticMessage:(NSString *)message
{
for (int i = 0; i < 20; i++) {
UILabel *messageLabel = [[UILabel alloc] init];

// Configure the label's colors and text
messageLabel.backgroundColor = [UIColor clearColor];
messageLabel.textColor = [UIColor whiteColor];
messageLabel.text = message;

// This method resizes the label, which will be relative
// to the text that it is displaying
[messageLabel sizeToFit];

// Get a random x value that fits within the hypnosis view's width
int width = self.view.bounds.size.width - messageLabel.bounds.size.width;
int x = arc4random_uniform(width);

// Get a random y value that fits within the hypnosis view's height
int height = self.view.bounds.size.height - messageLabel.bounds.size.height;
int y = arc4random_uniform(height);

// Update the label's frame
CGRect frame = messageLabel.frame;
frame.origin = CGPointMake(x, y);
messageLabel.frame = frame;

// Add the label to the hierarchy
[self.view addSubview:messageLabel];

UIInterpolatingMotionEffect *motionEffect;
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = @-25;
motionEffect.maximumRelativeValue = @25;
[messageLabel addMotionEffect:motionEffect];

motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
motionEffect.minimumRelativeValue = @-25;
motionEffect.maximumRelativeValue = @25;
[messageLabel addMotionEffect:motionEffect];
}
}

@end

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!