Cách thêm nút 'Xong' vào bàn phím numpad trong iOS


84

Vì vậy, bàn phím numpad không đi kèm với nút 'Xong' hoặc 'Tiếp theo' theo mặc định, vì vậy tôi muốn thêm một nút. Trong iOS 6 trở xuống, có một số thủ thuật để thêm nút vào bàn phím nhưng chúng dường như không hoạt động trong iOS 7.

Đầu tiên tôi đăng ký bàn phím hiển thị thông báo

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

Sau đó, tôi cố gắng thêm một nút khi bàn phím hiển thị:

- (void)keyboardWillShow:(NSNotification *)note 
{
    // create custom button
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeSystem];
    doneButton.frame = CGRectMake(0, 50, 106, 53);
    doneButton.adjustsImageWhenHighlighted = NO;
    [doneButton setTitle:@"Done" forState:UIControlStateNormal];
    [doneButton addTarget:self action:@selector(dismissKeyboard) forControlEvents:UIControlEventTouchUpInside];

    // locate keyboard view
    UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    UIView* keyboard;
    for(int i=0; i<[tempWindow.subviews count]; i++) 
    {
        keyboard = [tempWindow.subviews objectAtIndex:i];
        // keyboard view found; add the custom button to it
        if([[keyboard description] hasPrefix:@"UIKeyboard"] == YES)
        [keyboard addSubview:doneButton];
    }
}

Nhưng vòng lặp for không chạy vì nó không tìm thấy bất kỳ lượt xem phụ nào. Bất kỳ đề xuất? Tôi không thể tìm thấy bất kỳ giải pháp nào cho iOS7, vậy có cách nào khác mà tôi phải thực hiện việc này không?

Chỉnh sửa: Cảm ơn vì tất cả các đề xuất cho những người thanh công cụ nhưng tôi không muốn đi xuống tuyến đường đó vì tôi khá nghèo về không gian (và nó hơi xấu).


Đã thử bài này? neoos.ch/blog/…
Anil

@Anil Cách tùy chỉnh UIKeyboard đó bị apple cấm.
βhargavḯ

Kiểm tra với UIKeyboardDidShowNotification.
Praveen Matanam


2
Tôi không thực sự muốn thêm thanh công cụ, tôi muốn đặt nút ngay trên bàn phím.
George McKibbin

Câu trả lời:


26

Đây là một cách đơn giản để chiếu một nút đã hoàn thành trong bàn phím số iOS7. Trong phương thức ủy quyền dưới đây của UITextField, hãy thêm thông báo cho màn hình bàn phím.

-(void)textFieldDidBeginEditing:(UITextField *)textField {

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];
}

Bây giờ thực hiện phương pháp keyboardWillShownhư dưới đây. Ở đây, chúng ta cần phải chăm sóc thêm cho iOS7.

- (void)keyboardWillShow:(NSNotification *)note {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:[UIImage imageNamed:@"doneButtonNormal.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"doneButtonPressed.png"] forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIView *keyboardView = [[[[[UIApplication sharedApplication] windows] lastObject] subviews] firstObject];
        [doneButton setFrame:CGRectMake(0, keyboardView.frame.size.height - 53, 106, 53)];
        [keyboardView addSubview:doneButton];
        [keyboardView bringSubviewToFront:doneButton];

        [UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]-.02
                              delay:.0
                            options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]
                         animations:^{
                             self.view.frame = CGRectOffset(self.view.frame, 0, 0);
                         } completion:nil];
    });
}else {
    // locate keyboard view
    dispatch_async(dispatch_get_main_queue(), ^{
        UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
        UIView* keyboard;
        for(int i=0; i<[tempWindow.subviews count]; i++) {
            keyboard = [tempWindow.subviews objectAtIndex:i];
            // keyboard view found; add the custom button to it
            if([[keyboard description] hasPrefix:@"UIKeyboard"] == YES)
                [keyboard addSubview:doneButton];
        }
    });
  }
}

Bây giờ hãy thêm macro này vào tiêu đề phù hợp để phát hiện SYSTEM_VERSION

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)


1
Cảm ơn, đây là những gì tôi muốn :) Thật không may Nếu đã có một bàn phím trên màn hình và sau đó bạn chuyển sang trường cần bàn phím numpad thì keyBoardWillShow không được gọi. Nhưng cảm ơn, một bước đi đúng hướng haha.
George McKibbin

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO tại sao không phải là NSFoundationVersionNumber> NSFoundationVersionNumber_iOS_6_0? Và tôi kiểm tra nó, NSFoundationVersionNumber_iOS_5_0 tốt hơn
govo

Dispatch_async không phải là phương pháp đáng tin cậy nhất để hack vào bàn phím ở đây. :(
Predbird

7
trong iOS8, nút hoàn thành này không ẩn, Sau khi loại bỏ bàn phím.
Hemant Chittora

2
Câu trả lời này, mặc dù thông minh, nhưng chắc chắn sẽ bị phá vỡ.
SwiftArchitect

187

Cách tiếp cận an toàn hơn nhiều là sử dụng một UIToolBarvới DoneNút là inputAccessoryView.


Mã mẫu:

UIToolbar *keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
                                                               style:UIBarButtonItemStyleBordered target:self
                                                              action:@selector(doneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
txtField.inputAccessoryView = keyboardDoneButtonView;

-doneClickedPhương thức của bạn sẽ giống như sau:

- (IBAction)doneClicked:(id)sender
{
    NSLog(@"Done Clicked.");
    [self.view endEditing:YES];
}

Mã Swift mẫu:

let keyboardDoneButtonView = UIToolbar.init()
keyboardDoneButtonView.sizeToFit()
let doneButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Done, 
                                                   target: self, 
                                                   action: Selector("doneClicked:")))    

keyboardDoneButtonView.items = [doneButton]
textFieldInput.inputAccessoryView = keyboardDoneButtonView

-doneClickedPhương thức của bạn sẽ giống như sau:

func doneClicked(sender: AnyObject) {
  self.view.endEditing(true)
}

Tôi có thể phải kết thúc việc này. Tôi không thực sự thích nó chiếm bao nhiêu dung lượng.
George McKibbin

3
@GeorgeMcKibbin: Không phải là vấn đề ở đây vì khoảng trống sẽ chỉ chiếm không gian đó khi bạn đang nhập. Ngoài ra, theo mình cách làm này tốt hơn rất nhiều so với việc làm lộn xộn với Bàn phím mà Apple thường không thích.
Bhavin

Khi tôi làm điều này, tôi chỉ nhận được thanh công cụ ở cuối màn hình và bàn phím không còn xuất hiện nữa. Suy nghĩ?
Chris

câu trả lời tuyệt vời, chỉ là một miếng ngon, arrayWithObjects được unspokenly phản đối ủng hộ literals: [NSArray arrayWithObjects: doneButton, nil] => @ [doneButton]
Austin

1
từ iOS 8.0 UIBarButtonItemStyleBorderedkhông được sử dụng nữa UIBarButtonItemStyleDonehoặcUIBarButtonItemStylePlain
Nazir

131

Cách dễ dàng hơn:

Swift 3.0 trở lên :

func addDoneButton() {
    let keyboardToolbar = UIToolbar()
    keyboardToolbar.sizeToFit()
    let flexBarButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
        target: nil, action: nil)
    let doneBarButton = UIBarButtonItem(barButtonSystemItem: .done,
        target: view, action: #selector(UIView.endEditing(_:)))
    keyboardToolbar.items = [flexBarButton, doneBarButton]
    textField.inputAccessoryView = keyboardToolbar
}

Swift 2.3 trở xuống :

func addDoneButton() {
    let keyboardToolbar = UIToolbar()
    keyboardToolbar.sizeToFit()
    let flexBarButton = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace,
        target: nil, action: nil)
    let doneBarButton = UIBarButtonItem(barButtonSystemItem: .Done,
        target: view, action: #selector(UIView.endEditing(_:)))
    keyboardToolbar.items = [flexBarButton, doneBarButton]
    textField.inputAccessoryView = keyboardToolbar
}

Mục tiêu C :

- (void)addDoneButton {
    UIToolbar* keyboardToolbar = [[UIToolbar alloc] init];
    [keyboardToolbar sizeToFit];
    UIBarButtonItem *flexBarButton = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
    target:nil action:nil];
    UIBarButtonItem *doneBarButton = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemDone
    target:self.view action:@selector(endEditing:)];
    keyboardToolbar.items = @[flexBarButton, doneBarButton];
    self.textField.inputAccessoryView = keyboardToolbar;
}

BIÊN TẬP:

Tôi đã tạo một thư viện hữu ích có tên là DCKit , đã có sẵn thanh công cụ:

Xong thanh công cụ phía trên bàn phím trong iOS (với việc sử dụng thư viện DCKit)

Nó cũng có nhiều tính năng thú vị khác.


1
Có vẻ như đối với tôi, bạn đã thêm một nút thanh flex vào câu trả lời của Bhavin từ 1 năm trước như một câu trả lời mới để tôi có thể biết lý do tại sao ai đó lại bình chọn nó. Có lẽ tôi cũng bỏ lỡ điều gì đó ở đây?
Mark McCorkle

2
Vâng, tôi không sử dụng initWithTitle:@"Done", tôi sử dụng initWithBarButtonSystemItem:UIBarButtonSystemItemDonethay thế. Thao tác này sẽ trả về nút thanh Xong tiêu chuẩn của Apple. Hơn nữa, nó sẽ được bản địa hóa
Andrey Gordeev

3
Điều này nên được thêm vào như một sự cải tiến (bình luận) cho câu trả lời đúng trước đó IMO hoặc mong đợi phiếu bầu giảm. Một câu trả lời mới nên liên quan đến một cách tiếp cận khác với câu hỏi ban đầu, không phải là một cải tiến cho câu hỏi hiện có. Tuy nhiên, cảm ơn bạn đã cải thiện. ;-)
Mark McCorkle

4
Không, tôi không nghĩ vậy. Nhận xét không phải được sử dụng để viết code :)
Andrey Gordeev

13

Chỉ dựa trên các câu trả lời ở trên với phiên bản Swift vì tôi phải dịch nó:

   @IBOutlet weak var numberTextField: UITextField!

    override func viewDidLoad() {
        addDoneButtonTo(numberTextField)
    }

    // MARK: Done for numberTextField

    private func addDoneButtonTo(textField: UITextField) {
        let flexBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
        let doneBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "didTapDone:")
        let keyboardToolbar = UIToolbar()
        keyboardToolbar.sizeToFit()
        keyboardToolbar.items = [flexBarButton, doneBarButton]
        textField.inputAccessoryView = keyboardToolbar
    }

    func didTapDone(sender: AnyObject?) {
        numberTextField.endEditing(true)
    }

3

Bạn có thể dùng

myTextField.inputAccessoryView = _inputView;

chế độ xem phụ kiện đầu vào là chế độ xem luôn xuất hiện trên bàn phím và loại bỏ với [textfield resignFirstResponder]

đặt donetrên chế độ xem đầu vào và thực hiện phản hồi đầu tiên của các trường văn bản.



2
enter code here

1. register the controller to the notification

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Keyboard events
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}

2. don't forget to remove the controller from the notification centre

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self.view endEditing:YES];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

3. implement keyboard notification handlers

- (void)keyboardWillShow:(NSNotification *)notification {

// create custom button
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
    doneButton.frame = CGRectMake(0, 107, 106, 53);
    [doneButton setTitle:@"Done" forState:UIControlStateNormal];
    [doneButton addTarget:self  action:@selector(doneButton:)forControlEvents:UIControlEventTouchUpInside];

// save the reference to the button in order to use it in keyboardWillHide method
   self.donekeyBoardBtn = doneButton;

// to my mind no need to search for subviews
   UIWindow *windowContainigKeyboard = [[[UIApplication sharedApplication] windows]  lastObject];
   [windowContainigKeyboard addSubview:self.donekeyBoardBtn];
   self.donekeyBoardBtn.frame = CGRectMake(0., CGRectGetHeight(w.frame) -  CGRectGetHeight(self.donekeyBoardBtn.frame), CGRectGetWidth(self.donekeyBoardBtn.frame), CGRectGetHeight(self.donekeyBoardBtn.frame));
}

- (void)keyboardWillHide:(NSNotification *)notification {

    [self.donekeyBoardBtn removeFromSuperview];
}

4. implement done button action

- (void)doneButton:(id)sender{
   // add needed implementation
      [self.view endEditing:YES]; 
}

Tôi đã triển khai câu trả lời của bạn rất giống với những gì tôi phải làm. Cảm ơn. Nhưng nút không xuất hiện như một đối tượng hoạt hình, khi bàn phím hiển thị.
Arpit B Parekh,

1

Bạn cần phát hiện xem mình đang sử dụng điện thoại hay iPad vì iPad thực hiện phím quay lại trên bàn phím "số"


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.