IOS 学习笔记 UITextView UITextField 协议
目录
3 UITextView 和 UITextViewDelegate
4 UITextField 和 UITextFieldDelegate
1 UITextView & UITextField
1.1 UITextView
UITextView显示多行文本视图,接受编辑输入,类似于文本编辑器,获取焦点的时候会从底部弹出软键盘输入
1.2 UITextField
UITextField类似输入框,比如可用作search输入框,接受文本输入,获取焦点的时候会从底部弹出软键盘输入
如下图
2 Delegate
Delegate委托协议,有点类似于对接口类的实现,比如Android中Activity实现View.OnClickListener,当有Class实现了View.OnClickListener,那么就需要实现其接口方法onClick(View v),这里Delegate中也会存在相应的回调函数,比如UITextViewDelegate和UITextFieldDelegate各字都有自己可回调的函数。这是通过协议的方式给视图添加回调是IOS的特色。
2.1 UITextViewDelegate
UITextViewDelegate源码
@protocol UITextViewDelegate <NSObject, UIScrollViewDelegate>
@optional
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;
- (BOOL)textViewShouldEndEditing:(UITextView *)textView;
- (void)textViewDidBeginEditing:(UITextView *)textView;
- (void)textViewDidEndEditing:(UITextView *)textView;
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
- (void)textViewDidChange:(UITextView *)textView;
- (void)textViewDidChangeSelection:(UITextView *)textView;
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction NS_AVAILABLE_IOS(10_0);
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction NS_AVAILABLE_IOS(10_0);
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithTextAttachment:inRange:forInteractionType: instead");
@end
从上面源码中可以看到UITextViewDelegate中包含了
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
- (void)textViewDidChange:(UITextView *)textView;
- (void)textViewDidChangeSelection:(UITextView *)textView;
等一系列的回调函数,虽然没有给说明,但是函数名称却很清楚的表明了自己的作用。
2.2 UITextFieldDelegate
UITextFieldDelegate源码
@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
从源码中可以看到
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; // return NO to disallow editing.等8个回调函数
分别在用户和UITextView进行交互的各个阶段被回调。后面的注释写的很清楚,比如textFieldShouldReturn函数会在视图UITextView接受输入后,软件盘的return键被按下的时候回调。
3 UITextView 和 UITextViewDelegate
要给UITextView添加响应事件可以通过UITextViewDelegate协议来进行,那么怎样将UITextView的响应事件同UITextViewDelegate的回调函数相关连起来呢?注意如果不关联是无法回调到对应的函数的。
这里有两种方式:Interface Builder、代码实现
3.1 Interface Builder实现
通过在xcode中拖拽(Interface Builder实现,这样说不易于理解,因为刚开始学习,对这Interface Builder概念可能不了解),如下图
见鼠标放在UITextField或者UITextView,右键点击(mac触摸板是双指点击)弹出对话框,选择delegate,将光标点按在后面⭕️上,这时候⭕️中间会出现一个“+”,然后拖拽到右边的View Controller上,这时候View Controller上会有一个蓝色这框表示它被选中了,然后松手
(这里不好截图操作,我就直接画出来的)
经过上面操作,弹出的选项对话框delegate选项后面的空心圆圈就变成实心了,如下图,表示delegate和View Controller建立了绑定关系
上面用的是UITextField做的例子,UITextView是相同操作
下面是实例,
源码代码如下
#import "ViewController.h"
@interface ViewController ()<UITextFieldDelegate, UITextViewDelegate>
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark -- 实现 UITextViewDelegate委托协议中一个方法,当UITextView中文字输入有变化的时候会被调用
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSLog(@"textView 被调用了,变化的部分是 %@", text);
return YES;
}
@end
界面如下:
然后通过拖拽的方法将UITextView的delegate同View Controller联系起来,我们可以看到在源码中便没有相关的代码表明UITextViewDelegate协议和UITextView绑定起来了,这都是xcode帮我实现了,到目前的为止我们主观上是看不到任何线索的,但是背后毋庸置疑肯定会有对应的代码将之相关联,这里暂时不做深究。
当我们在TextView中输入abc的时候控制台会有打印如下:
2019-04-12 21:53:28.979854+0800 TextView_TextField[12595:439931] textView 被调用了,变化的部分是 a
2019-04-12 21:53:29.616090+0800 TextView_TextField[12595:439931] textView 被调用了,变化的部分是 b
2019-04-12 21:53:30.099341+0800 TextView_TextField[12595:439931] textView 被调用了,变化的部分是 c
2019-04-12 21:56:11.521134+0800 TextView_TextField[12595:439931] textView 被调用了,变化的部分是
2019-04-12 21:56:11.944165+0800 TextView_TextField[12595:439931] textView 被调用了,变化的部分是
2019-04-12 21:56:12.281370+0800 TextView_TextField[12595:439931] textView 被调用了,变化的部分是
因为textview函数中有:
NSLog(@"textView 被调用了,变化的部分是 %@", text);
text会取出变化的字符,这里是一个个字母输入的,但是如果我们删除,显示的其实是空字符,函数中很清楚,text是replacementText
3.2 通过代码添加
上面掩饰了通过非代码的方式让UITextView 和 UITextViewDelegate相关联,然后UITextViewDelegate中的某一个回调函数被调用了,下面将通过代码的方式将让UITextView 和 UITextViewDelegate相关联,
1)首先取消掉UITextView 和 UITextViewDelegate的的关系
选中Main.storyboard中的TextView,mac触摸板双指点击弹出如下选择框,点击红色小框中的X,取消掉绑定关系
2)在代码中添加UITextView 和 UITextViewDelegate的关联关系
这句话将UITextView和UITextViewDelegate协议关联:self.textView.delegate = self;
可以前后做一下对比实验,去掉这句话之后看在控制台是否有对应的输出
#import "ViewController.h"
@interface ViewController ()<UITextFieldDelegate, UITextViewDelegate>
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
forControlEvents:UIControlEventTouchDown];
self.textView.delegate = self;//这句话将UITextView和UITextViewDelegate协议关联
self.textField.delegate = self;//这句话将UITextField和UITextFieldDelegate协议关联
}
#pragma mark -- 实现 UITextViewDelegate委托协议中一个方法,当UITextView中文字输入有变化的时候会被调用
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSLog(@"textView 被调用了,变化的部分是 %@", text);
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(@"UITextField retrun 按键被调用了");
return YES;
}
@end
输出结果
2019-04-12 22:15:19.800323+0800 TextView_TextField[12832:448693] textView 被调用了,变化的部分是 o
2019-04-12 22:15:19.923160+0800 TextView_TextField[12832:448693] textView 被调用了,变化的部分是 k
2019-04-12 22:15:24.377870+0800 TextView_TextField[12832:448693] UITextField retrun 按键被调用了
4 UITextField 和 UITextFieldDelegate
同上,这里就不做赘述了。
5 Button的点击事件
上面类似于,在android中将一个Button和其点击事件的回调函数连接起来,只不过IOS使用了协议来实现,具体内在的关联,以后在分析,看起来似乎没有android中的直观和简单,
mButton.setOnClickListener(this);//this表示当前实现了View.OnClickListener的Class,
//或者直接
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
也就是通过setOnClickListener函数给对应的view设置一个回调兼听监听即可。这里类比Android
5.1 添加UIButton并添加引用
那么在IOS开发中使用OC是怎么给一个UIView添加事件的呢?
1)在故事板中添加一个UIButton如下图
2)然后在ViewController.m中添加UIButton的引用
有两种方式
方式一
先在代码中手写@property (weak, nonatomic) IBOutlet UIButton *button;然后将其前面的小圆圈
这句话需要跟故事板中的Button绑定起来,通过拖拽的连线的方式,选中上面添加的代码前的小圆点到故事板中的button视图,如下图:
方式二
让xcode自动生成,按住control键,按照下图的箭头的路线拖拽到小框的位置,只要在@interface ViewController和@end之间即可,不一定非要是图中小红框标示的位置,然后在Name框后面输入,比如button,然后点击Connect按钮,就会自动生成方法一中手写的代码
下面是通过代码使用button
#import "ViewController.h"
@interface ViewController ()<UITextFieldDelegate, UITextViewDelegate>
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.button addTarget:self action:@selector(onButtonClick) forControlEvents:UIControlEventTouchDown];
}
-(void)onButtonClick{
NSLog(@"########## onButtonClick ");
}
@end
5.2 代码分析
[self.button addTarget:self action:@selector(onButtonClick) forControlEvents:UIControlEventTouchDown];
上面代码便是给button添加了一个action,这个action的函数名是onButtonClick,注意一定要写成@selector(onButtonClick) 这里的onButtonClick不带入参
这里就简单的举例,至于@selector(onButtonClick)等函数为什么要这样写 以后在说明,这里先大概了解,有个整体把握。
推荐阅读
-
iOS学习笔记-139.RunLoop07——Runloop处理流程
-
IOS UI学习教程之设置UITextField各种属性
-
iOS bounds学习笔记以及仿写UIScrollView部分功能详解
-
ios蓝牙开发学习笔记(四)ios蓝牙应用的后台处理
-
iOS 绘制 cell --- 新手学习笔记
-
iOS UITextField的代理
的几点笔记 -
Xamarin 学习笔记 - 配置环境(Windows & iOS)
-
iOS学习笔记-139.RunLoop07——Runloop处理流程
-
iOS学习笔记-128.SDWebImage4——框架内部调用简单分析
-
iOS学习笔记-147.网络07——NSURLConnection04_简单JSON的解析