web-dev-qa-db-ja.com

iPhone OS 4のテンキーに「完了」ボタンを表示するにはどうすればよいですか?

IPhoneのテンキーキーボードに[完了]ボタンを追加したいのですが。左下にはそのようなボタンだけの便利なスペースさえあります。

以前は、 Question 584538 および Luzian Scherrerの優れたブログ投稿 で説明されているものと同様のトリックを使用していましたが、iOS4では機能しなくなりました。カスタムinputViewですが、自分で書くのではなく、Appleのキーボードを拡張したいと思います。

標準キーボードにビューを追加する新しい方法はありますか?誰かがこれのためにOSSinputViewを公開しましたか?別の方法はありますか?

24
Will Harris

Luzian Scherrerのブログ投稿で説明されている手法はiOS 4.0で機能します

ボタンをキーボードに追加するコードは、キーボードウィンドウのサブビューが作成される前に(4.0では)呼び出されるtextFieldDidBeginEditing:デリゲートメソッドから呼び出されていたため、失敗していました。 UIKeyboardWillShowNotificationが観察されたときにコードを呼び出すことで問題を修正しましたが、これは十分に遅く発生します。

3
Will Harris

[適用]ボタンと[キャンセル]ボタンを使用してinputAccessoryViewを追加し、それを使用してテンキーを閉じることができます。

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];
}
89
Luda

私はこれを機能させました。ここのコードを参照してください: http://Gist.github.com/454844

2つの問題がありました:

  1. UIKeyboardWillShowNotificationは、キーボードビューが存在する前に送信されますが、次の実行ループパスで実行するようにコードをスケジュールすると、存在します。したがって、視覚的に不快なDidShowを気にする必要はありません。

  2. IOS 4では、UIKeyboardビューはビュー階層の他の場所にありました。

6
Henrik N

コードをリファクタリングしてgithubに配置しました。

https://github.com/dazuiba/dz-numberpad-done-helper

3
dazuiba

私はこれをバグとしてAppleに提出しました。InterfaceBuilderでは、開発者がテンキーのキーボードタイプのリターンキータイプを指定できます。バグ番号8759674。

Appleはフォローアップして、この問題は以前にバグID#5885964として記録されており、8759674をクローズしたと述べました。

2
Alan Hancock

このキーボード通知コードを使用して、数字キーパッドの完了ボタンを作成できます。最後に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];
}
1
sinh99

テンキーの水平バージョンを有効にするバージョンを作成しました... 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];        
    }
1
hokkuk