为数据输入自定义视图 <- iOS文本编程指南
UIKit允许app用自定义的输入视图替换系统键盘。它还允许app有一个附加视图在系统键盘或自定义输入视图之上。另外,它允许app在用户点击输入视图或输入附件视图的控件的时候播放键盘敲击音。
输入视图和输入附加视图
UIKit框架包括对自定义输入视图和输入附加视图的支持。当用户在视图中编辑文本或其他数据格式的时候,app可以用自己的输入视图来替换系统键盘。例如,app可以使用自定以输入视图来输入符文字母。你还可以给系统键盘或自定义输入视图添加输入附加视图,这个附加视图在主输入视图之上,例如,以某种方式影响文本的控件,或显示相关文本的一些信息。
如果你的app使用UITextView和UITextField对象来编辑文本,想要获取该功能,可以简单的分配自定义视图到inputView和inputAccessoryView属性。这些自定义视图在文本对象变为第一响应者的时候显示。
你的输入视图和输入附加视图不限于框架提供的文本对象。任何直接或者间接继承UIResponder的类(通常是自定义视图)都可以指定它自己的输入视图和输入附加视图。UIResponder类为输入视图和输入附加视图声明了两个属性:
@property (readonly, retain) UIView *inputView;
@property (readonly, retain) UIView *inputAccessoryView;
当响应对象变为第一响应者并且inputView(或者inputAccessoryView)不是nil的时候,UIKit可以动画的把输入视图放置在父视图之下(或者把输入附加视图放置在输入视图之上)。第一响应者可以通过调用UIResponder的reloadInputViews方法来重新家在输入和附加视图。
UITextView类重写了inputView和inputAccessoryView属性。UITextView对象的客户端只需要获取输入和输入附加视图(可以通过加载nib文件或通过代码的方式创建),并把它们分配给对象的属性。自定义视图类(以及UIResponder的其他子类)应该声明这两个属性以及它们的后背实例变量(backing instance variables)的一个或两个,并重写属性的getter方法,不要合成属性的访问器方法。在它们的getter方法实现中,它们应该返回视图,如果它不存在,就应该加载或创建。
你在定义输入视图或输入附加视图时有很大的灵活性。尽管这些视图的高度可以随你喜欢,但是它们应该有和系统键盘一样的宽度。如果UIKit在它的autoresizing mask中遇到带有UIViewAutoresizingFlexibleHeight值的输入视图,它会把高度设置为和键盘匹配。输入视图和输入附加视图可能拥有的子视图(例如控件)是没有数量限制的。更多输入视图和输入附加视图的指导,参见iOS Human Interface Guidelines。
想要在运行的时候加载nib文件,首先在Interface Builder中创建输入视图或输入附加视图。然后在运行时得到app的主束,并且在其上调用loadNibNamed:owner:options: ,传递nib文件的名字、nib文件的File‘s Owner、以及任何可选项。该方法返回nib文件中的顶层对象的数组,其中包括了输入视图和输入附加视图。把该视图分配给它的相应属性。更多关于此主题的内容,参见Resource Programming Guide中的Nib Files 。
代码清单 6-1说明了一个自定义视图类在inputAccessoryView的getter方法中懒创建它的输入附加视图。
代码清单 6-1 用编程的方式创建输入附加视图
- (UIView *)inputAccessoryView {
if (!inputAccessoryView) {
CGRect accessFrame = CGRectMake(0.0, 0.0, 768.0, 77.0);
inputAccessoryView = [[UIView alloc] initWithFrame:accessFrame];
inputAccessoryView.backgroundColor = [UIColor blueColor];
UIButton *compButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
compButton.frame = CGRectMake(313.0, 20.0, 158.0, 37.0);
[compButton setTitle: @"Word Completions" forState:UIControlStateNormal];
[compButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[compButton addTarget:self action:@selector(completeCurrentWord:)
forControlEvents:UIControlEventTouchUpInside];
[inputAccessoryView addSubview:compButton];
}
return inputAccessoryView;
}
输入视图和输入附加视图的自视图可以是你希望的任何东西。如果它们是按钮或者其他控件,你需要为每个控件指定目标和方法,并且实现相关的动作方法来执行数据输入或操作。
就像系统键盘一样,UIKit也发送UIKeyboardWillShowNotification, UIKeyboardDidShowNotification, UIKeyboardWillHideNotification, 和 UIKeyboardDidHideNotification 通知。该对象观察这些通知,可以得到输入视图和输入附加视图的相关的几何信息,并调整相应的编辑视图。有关示例和相关信息,参见Keyboards and Input Methods。
播放输入点击
当用户点击自定义输入视图和键盘附加视图的时候,你可以播放标准的系统键盘点击音。首先,在你的输入视图中采用UIInputViewAudioFeedback协议。然后,当响应该视图的键盘点击的时候调用playInputClick方法。
采用UIInputViewAudioFeedback协议
执行以下三个步骤来采用UIInputViewAudioFeedback协议:
- 在你的Xcode项目中,创建UIView类的子类。在头文件中,指明该子类遵守UIInputViewAudioFeedback协议,就像这样:
@interface KeyboardAccessoryView : UIView <UIInputViewAudioFeedback> {
}
- 在你的UIView子类的实现文件中,实现enableInputClicksWhenVisible方法,如下所示:
- (BOOL) enableInputClicksWhenVisible {
return YES;
}
- 最后,在你的自定输入或附加视图的Interface Builder文件中,选择该视图对象。在身份检查器中,设置该对象的类为你的UIView子类。
播放输入点击
想要在点击自定义输入或键盘附加视图的键时播放输入点击音,首先要确认该视图采用了UIInputViewAudioFeedback协议。然后,为每个点击提供你想要的点击声音,调用UIDevice类的playInputClick方法,如下所示:
- (void) playClickForCustomKeyTap {
[[UIDevice currentDevice] playInputClick];
}
系统自动为自定义输入点击管理音频会话,包括根据需要的音频回避。(更多关于音频会话的信息,参见Audio Session Programming Guide。)