IPhoneのテンキーキーボードに[完了]ボタンを追加したいのですが。左下にはそのようなボタンだけの便利なスペースさえあります。
以前は、 Question 584538 および Luzian Scherrerの優れたブログ投稿 で説明されているものと同様のトリックを使用していましたが、iOS4では機能しなくなりました。カスタムinputViewですが、自分で書くのではなく、Appleのキーボードを拡張したいと思います。
標準キーボードにビューを追加する新しい方法はありますか?誰かがこれのためにOSSinputViewを公開しましたか?別の方法はありますか?
Luzian Scherrerのブログ投稿で説明されている手法はiOS 4.0で機能します。
ボタンをキーボードに追加するコードは、キーボードウィンドウのサブビューが作成される前に(4.0では)呼び出されるtextFieldDidBeginEditing:
デリゲートメソッドから呼び出されていたため、失敗していました。 UIKeyboardWillShowNotification
が観察されたときにコードを呼び出すことで問題を修正しましたが、これは十分に遅く発生します。
[適用]ボタンと[キャンセル]ボタンを使用して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];
}
私はこれを機能させました。ここのコードを参照してください: http://Gist.github.com/454844
2つの問題がありました:
UIKeyboardWillShowNotification
は、キーボードビューが存在する前に送信されますが、次の実行ループパスで実行するようにコードをスケジュールすると、存在します。したがって、視覚的に不快なDidShow
を気にする必要はありません。
IOS 4では、UIKeyboard
ビューはビュー階層の他の場所にありました。
コードをリファクタリングしてgithubに配置しました。
私はこれをバグとしてAppleに提出しました。InterfaceBuilderでは、開発者がテンキーのキーボードタイプのリターンキータイプを指定できます。バグ番号8759674。
Appleはフォローアップして、この問題は以前にバグID#5885964として記録されており、8759674をクローズしたと述べました。
このキーボード通知コードを使用して、数字キーパッドの完了ボタンを作成できます。最後に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];
}
テンキーの水平バージョンを有効にするバージョンを作成しました... Luzian Scherrerのブログで説明されている手法に接続し、2つの追加の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];
}