我想在iPhone数字键盘键盘上添加一个完成按钮。这样的按钮左下方甚至还有一个方便的空间。
以前,我使用了与Question 584538和Luzian Scherrer's excellent blog post中描述的类似技巧,但是在iOS 4中停止了工作。我可以通过创建自定义inputView来实现,但我更喜欢扩展Apple的键盘,而不是自己写。
是否有新方法将视图添加到标准键盘?有人为此发布了OSS inputView吗?还有另一种方式吗?
答案 0 :(得分:89)
您可以使用“应用”和“取消”按钮添加inputAccessoryView
,然后用数字键盘关闭。
- (void)viewDidLoad
{
[super viewDidLoad];
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelNumberPad)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:@"Apply" style:UIBarButtonItemStyleDone target:self action:@selector(doneWithNumberPad)],
nil];
numberTextField.inputAccessoryView = numberToolbar;
}
-(void)cancelNumberPad{
[numberTextField resignFirstResponder];
numberTextField.text = @"";
}
-(void)doneWithNumberPad{
NSString *numberFromTheKeyboard = numberTextField.text;
[numberTextField resignFirstResponder];
}
答案 1 :(得分:6)
我得到了这个工作。请参阅此处的代码:http://gist.github.com/454844
有两个问题:
UIKeyboardWillShowNotification
在键盘视图存在之前发送,但是您安排代码在下一个运行循环传递中运行,它们确实存在。因此,您不必费心使用视觉上不那么令人愉悦的DidShow
。
在iOS 4上,UIKeyboard
视图位于视图层次结构的其他位置。
答案 2 :(得分:3)
Luzian Scherrer's blog post 中描述的技术在iOS 4.0中有效。
我将键盘添加到键盘的代码失败了,因为它是从textFieldDidBeginEditing:
委托方法调用的,在创建键盘窗口的子视图之前调用(4.0)。我通过在观察到UIKeyboardWillShowNotification
时调用我的代码来解决问题,这种情况发生得太晚了。
答案 3 :(得分:3)
我重构了代码并将其放在github上。
答案 4 :(得分:2)
我已将此作为错误提交给Apple。 Interface Builder允许开发人员为数字键盘的键盘类型指定返回键类型。错误号8759674。
苹果随后说,此问题以前已被记录为错误ID#5885964,他们已关闭8759674。答案 5 :(得分:1)
您可以使用此键盘通知代码在数字键盘上创建完成按钮。您必须在您的最后下载done.png图像。
在.h文件中
{ //Keyboard Hide
UIImage *numberPadDoneImageNormal;
UIImage *numberPadDoneImageHighlighted;
UIButton *numberPadDoneButton;
}
@property (nonatomic, retain) UIImage *numberPadDoneImageNormal;
@property (nonatomic, retain) UIImage *numberPadDoneImageHighlighted;
@property (nonatomic, retain) UIButton *numberPadDoneButton;
- (IBAction)numberPadDoneButton:(id)sender;
在.m文件中
@synthesize numberPadDoneImageNormal;
@synthesize numberPadDoneImageHighlighted;
@synthesize numberPadDoneButton;
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
if ([super initWithNibName:nibName bundle:nibBundle] == nil)
return nil;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
self.numberPadDoneImageNormal = [UIImage imageNamed:@"NumberDone.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"NumberDone.png"];
} else {
self.numberPadDoneImageNormal = [UIImage imageNamed:@"NumberDone.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"NumberDone.png"];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Add listener for keyboard display events
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
// Add listener for all text fields starting to be edited
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFieldDidBeginEditing:)
name:UITextFieldTextDidBeginEditingNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextFieldTextDidBeginEditingNotification
object:nil];
[super viewWillDisappear:animated];
}
- (UIView *)findFirstResponderUnder:(UIView *)root {
if (root.isFirstResponder)
return root;
for (UIView *subView in root.subviews) {
UIView *firstResponder = [self findFirstResponderUnder:subView];
if (firstResponder != nil)
return firstResponder;
}
return nil;
}
- (UITextField *)findFirstResponderTextField {
UIResponder *firstResponder = [self findFirstResponderUnder:[self.view window]];
if (![firstResponder isKindOfClass:[UITextField class]])
return nil;
return (UITextField *)firstResponder;
}
- (void)updateKeyboardButtonFor:(UITextField *)textField {
// Remove any previous button
[self.numberPadDoneButton removeFromSuperview];
self.numberPadDoneButton = nil;
// Does the text field use a number pad?
if (textField.keyboardType != UIKeyboardTypeNumberPad)
return;
// If there's no keyboard yet, don't do anything
if ([[[UIApplication sharedApplication] windows] count] < 2)
return;
UIWindow *keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
// Create new custom button
self.numberPadDoneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.numberPadDoneButton.frame = CGRectMake(0, 163, 106, 53);
self.numberPadDoneButton.adjustsImageWhenHighlighted = FALSE;
[self.numberPadDoneButton setTitle:@"Return" forState:UIControlStateNormal];
[self.numberPadDoneButton setFont:[UIFont boldSystemFontOfSize:18]];
[self.numberPadDoneButton setTitleColor:[UIColor colorWithRed:77.0f/255.0f green:84.0f/255.0f blue:98.0f/255.0f alpha:1.0] forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageNormal forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageHighlighted forState:UIControlStateHighlighted];
[self.numberPadDoneButton addTarget:self action:@selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
// Locate keyboard view and add button
NSString *keyboardPrefix = [[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2 ? @"<UIPeripheralHost" : @"<UIKeyboard";
for (UIView *subView in keyboardWindow.subviews) {
if ([[subView description] hasPrefix:keyboardPrefix]) {
[subView addSubview:self.numberPadDoneButton];
[self.numberPadDoneButton addTarget:self action:@selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
break;
}
}
}
- (void)textFieldDidBeginEditing:(NSNotification *)note {
[self updateKeyboardButtonFor:[note object]];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (void)keyboardDidShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (IBAction)numberPadDoneButton:(id)sender {
UITextField *textField = [self findFirstResponderTextField];
[textField resignFirstResponder];
}
- (void)dealloc {
[numberPadDoneImageNormal release];
[numberPadDoneImageHighlighted release];
[numberPadDoneButton release];
[super dealloc];
}
答案 6 :(得分:1)
我已经创建了一个版本来启用numpad的水平版本... 插入Luzian Scherrer博客中描述的技术并添加两个额外的png(此处未包含),并将“isLandscape”布尔值添加到“didRotateFromInterfaceOrientation”方法中。
@interface AlarmController ()
{
CGRect doneButtnRectVert;
CGRect doneButtnRectHorz;
CGRect doneButtnRect;
UIImage* DoneUpVert;
UIImage* DoneDownVert;
UIImage* DoneUpHorz;
UIImage* DoneDownHorz;
UIImage* DoneUp;
UIImage* DoneDown;
UIButton *oldDoneButton;
}
@end
//---------------------------------------------------------------------------
- (void)viewDidUnload
{
NSLog(@"viewDidUnload AlarmController");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification object:nil];
[super viewDidUnload];
}
//---------------------------------------------------------------------------
- (void)addButtonToKeyboard
{
NSLog(@"addButtonToKeyboard AlarmController");
if (isLandscape)
{
doneButtnRect = doneButtnRectHorz;
DoneUp = DoneUpHorz;
DoneDown = DoneDownHorz;
} else {
doneButtnRect = doneButtnRectVert;
DoneUp = DoneUpVert;
DoneDown = DoneDownVert;
}
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = doneButtnRect;
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:DoneUp forState:UIControlStateNormal];
[doneButton setImage:DoneDown forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(done:) forControlEvents:UIControlEventTouchUpInside];
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
{
if (oldDoneButton) [oldDoneButton removeFromSuperview];
[keyboard addSubview:doneButton];
}
}
oldDoneButton = doneButton;
}
//---------------------------------------------------------------------------
- (void)keyboardDidShow:(NSNotification *)note
{
NSLog(@"keyboardDidShow AlarmController");
[self addButtonToKeyboard];
}
#pragma mark -
#pragma mark meaty area...
//---------------------------------------------------------------------------
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(@"textFieldDidEndEditing AlarmController");
oldDoneButton = nil;
}
//---------------------------------------------------------------------------
- (void)viewDidLoad
{
NSLog(@"viewDidLoad AlarmController");
[super viewDidLoad];
doneButtnRectVert = CGRectMake(0, 163, 106, 53);
doneButtnRectHorz = CGRectMake(0, 122, 159, 40);
DoneUpVert = [UIImage imageNamed:@"DoneUp3.png"];
DoneDownVert = [UIImage imageNamed:@"DoneDown3.png"];
DoneUpHorz = [UIImage imageNamed:@"DoneUpHor.png"];
DoneDownHorz = [UIImage imageNamed:@"DoneDnHor.png"];
doneButtnRect = doneButtnRectVert;
DoneUp = DoneUpVert;
DoneDown = DoneDownVert;
oldDoneButton = nil;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil];
}