系统键盘
01.UITextField, UITextView这两个控件, 获得焦点时(becomeFirstResponder), 会弹出键盘, 失去焦点时(resignFirstResponder), 会收起键盘
02.UIView有一个便捷的方法[endEditing:], 可以收起与这个视图有关的键盘
03.通过注册UIKeyboardWillShowNotification等通知消息, 来获取键盘状态. 如果想要知道当前键盘高度, 这是唯一准确的办法.04.弹出的键盘, 并不在AppDelegate的那个window上, 而在另外一个UIRemoteKeyboardWindow上
自定义键盘
可以简单的认为, 键盘是属于UITextField(或UITextView)的子控件. 当UITextField获得焦点时, 键盘必然会弹出, 失去焦点时, 键盘必然会收起. 键盘的宽度始终等于当前屏幕的宽度. 以这些为参考, 我们来为自制的控件UITextBox(继承自UIView), 弄一个自制的键盘UICustomBoard.
01. 准备一个键盘. 随心所欲的写一个UICustomBoard(继承自UIView), 只需要注意它的尺寸, 键盘不可能比屏幕还大!
02. UITextBox需要能够获得焦点, 所以, 请重写三个方法:
- (BOOL)canBecomeFirstResponder;
- (BOOL)becomeFirstResponder;
- (BOOL)resignFirstResponder;
03. 告诉系统, UICustomBoard是UITextBox的键盘, 在UITextBox中声明下面这个属性:
@property (nonatomic, strong) UICustomBoard *inputView;
然后按command+鼠标左键, 会发现跳转到UIResponder的属性上了, 而此处的它是被标记为readonly的. 什么道理? 我不管!
回到UITextBox中, 我们生成一个UICustomBoard对象, 并赋值给self.inputView. 当然, 你可以用懒加载的方式, 在get方法中赋值.
04. 将UITextBox添加到视图上, 启动程序, 点击UITextBox, 让它获得焦点, 看看UICustomBoard弹出没.
另外, 我们注意到, 在UIResponder的inputView附近, 还有一个inputAccessoryView. 这个东西定制的方法和inputView相同. 但它是什么呢?回想一下企鹅的聊天界面, 无论切换成什么键盘, 总有个工具栏跟随着键盘, 就跟小跟班似得, 它就是inputAccessoryView.
样例代码
// UITextBox.m
#import "UITextBox.h"
#import "UICustomBoard.h"
@interface UITextBox()
@property (nonatomic, strong) UICustomBoard *inputView;
@end
@implementation UITextBox
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.inputView = [[UICustomBoard alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 200)];
}
return self;
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (BOOL)becomeFirstResponder
{
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
return [super resignFirstResponder];
}
@end
// UICustomBoard.m
#import "UICustomBoard.h"
@implementation UICustomBoard
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.backgroundColor = [UIColor darkGrayColor];
NSArray *titles = @[@"笑", @"哭", @"疯", @"傻"];
CGFloat bnw = self.bounds.size.width / titles.count;
CGFloat bnh = self.bounds.size.height;
for (int i = 0; i < titles.count; i++)
{
UIButton *button = [UIButton new];
[button setFrame:CGRectMake(i * bnw, 0, bnw, bnh)];
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
}
return self;
}
- (void)buttonPressed:(UIButton *)button
{
NSLog(@"You pressed %@", button.titleLabel.text);
}
@end