วิธีเพิ่มปุ่ม 'เสร็จสิ้น' ให้กับแป้นพิมพ์ตัวเลขใน iOS


84

ดังนั้นแป้นพิมพ์ numpad จึงไม่มีปุ่ม "เสร็จสิ้น" หรือ "ถัดไป" ตามค่าเริ่มต้นดังนั้นฉันจึงต้องการเพิ่ม ใน iOS 6 และต่ำกว่ามีเทคนิคบางอย่างในการเพิ่มปุ่มลงในแป้นพิมพ์ แต่ดูเหมือนจะไม่ทำงานใน iOS 7

ก่อนอื่นฉันสมัครใช้งานแป้นพิมพ์ที่แสดงการแจ้งเตือน

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

จากนั้นฉันพยายามเพิ่มปุ่มเมื่อแป้นพิมพ์ปรากฏขึ้น:

- (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];
    }
}

แต่ for loop ไม่ทำงานเนื่องจากไม่พบ subview ใด ๆ ข้อเสนอแนะใด ๆ ? ฉันไม่พบวิธีแก้ปัญหาใด ๆ สำหรับ iOS7 ดังนั้นมีวิธีอื่นที่ฉันควรทำหรือไม่?

แก้ไข: ขอบคุณสำหรับคำแนะนำทั้งหมดสำหรับแถบเครื่องมือ แต่ฉันไม่อยากลงไปในเส้นทางนั้นเพราะฉันค่อนข้างมีพื้นที่ไม่ดี (และมันก็น่าเกลียด)


พยายามโพสต์นี้? neoos.ch/blog/…
Anil

@Anil วิธีปรับแต่ง UIKeyboard นั้นเป็นสิ่งต้องห้ามโดย apple
βhargavḯ

ตรวจสอบกับ UIKeyboardDidShowNotification
Praveen Matanam


2
ฉันไม่ต้องการเพิ่มแถบเครื่องมือจริงๆฉันต้องการวางปุ่มบนแป้นพิมพ์
George McKibbin

คำตอบ:


26

นี่เป็นวิธีง่ายๆในการฉายปุ่มเสร็จสิ้นในปุ่มกด num ของ iOS7 ในวิธีการมอบสิทธิ์ด้านล่างของ UITextField ให้เพิ่มการแจ้งเตือนสำหรับการแสดงแป้นพิมพ์

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

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

ตอนนี้ใช้วิธีการkeyboardWillShowดังต่อไปนี้ ที่นี่เราต้องดูแลเป็นพิเศษสำหรับ 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];
        }
    });
  }
}

เพิ่มมาโครนี้ลงในส่วนหัวที่เหมาะสมเพื่อตรวจจับ SYSTEM_VERSION

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


1
ขอบคุณนี่คือสิ่งที่ฉันต้องการ :) น่าเสียดายหากมีแป้นพิมพ์อยู่แล้วบนหน้าจอแล้วคุณเปลี่ยนไปใช้ฟิลด์ที่ต้องใช้แป้นพิมพ์ตัวเลขแล้ว keyBoardWillShow จะไม่ถูกเรียก แต่ต้องขอบคุณก้าวไปในทิศทางที่ถูกต้องฮ่าฮ่า
George McKibbin

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO ทำไมไม่ NSFoundationVersionNumber> NSFoundationVersionNumber_iOS_6_0 และฉันทดสอบ NSFoundationVersionNumber_iOS_5_0 ดีกว่า
govo

dispatch_async ไม่ใช่วิธีที่น่าเชื่อถือที่สุดในการเจาะเข้าสู่แป้นพิมพ์ที่นี่ :(
Ben Affleck

7
ใน iOS8 ปุ่มเสร็จสิ้นนี้ไม่ได้ซ่อนอยู่หลังจากปิดแป้นพิมพ์
Hemant Chittora

2
คำตอบนี้แม้ว่าจะฉลาด แต่ก็ยังคงแตกสลาย
SwiftArchitect

187

วิธีการที่ปลอดภัยมากคือการใช้UIToolBarกับปุ่มเป็นDoneinputAccessoryView


รหัสตัวอย่าง:

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;

-doneClickedวิธีการของคุณควรมีลักษณะดังนี้:

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

ตัวอย่างโค้ด Swift:

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

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

-doneClickedวิธีการของคุณควรมีลักษณะดังนี้:

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

ฉันอาจจะต้องจบลงด้วยการทำสิ่งนี้ ฉันไม่ค่อยชอบที่จะใช้พื้นที่เท่าไหร่
George McKibbin

3
@GeorgeMcKibbin: ช่องว่างไม่ควรเป็นปัญหาที่นี่เนื่องจากจะใช้พื้นที่ดังกล่าวเฉพาะในขณะที่คุณกำลังพิมพ์ ตามที่ฉันพูดวิธีนี้ดีกว่าการยุ่งกับคีย์บอร์ดที่โดยปกติแล้ว Apple ไม่ชอบ
ภวินทร์

เมื่อฉันทำเช่นนี้ฉันจะได้รับแถบเครื่องมือที่ด้านล่างสุดของหน้าจอเท่านั้นและแป้นพิมพ์จะไม่ปรากฏอีกต่อไป ความคิด?
คริส

คำตอบที่ดีมีเพียงหนึ่ง tidbit arrayWithObjects เลิกใช้งานโดยไม่ต้องพูดเพื่อสนับสนุนตัวอักษร: [NSArray arrayWithObjects: doneButton, nil] => @ [doneButton]
Austin

1
จาก iOS 8.0 UIBarButtonItemStyleBorderedเลิกใช้งานแล้วUIBarButtonItemStyleDoneหรือUIBarButtonItemStylePlain
Nazir

131

วิธีที่ง่ายยิ่งขึ้น:

Swift 3.0 ขึ้นไป :

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 และต่ำกว่า :

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
}

วัตถุประสงค์ 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;
}

แก้ไข:

ฉันได้สร้างไลบรารีที่มีประโยชน์ชื่อDCKitซึ่งมีแถบเครื่องมืออยู่แล้ว:

ทำแถบเครื่องมือเหนือแป้นพิมพ์ใน iOS (โดยใช้ไลบรารี DCKit)

มันยังมีฟีเจอร์เด็ด ๆ อีกมากมาย


1
สำหรับฉันแล้วคุณได้เพิ่มปุ่มแถบดิ้นให้กับคำตอบของภวินทร์เมื่อ 1 ปีที่แล้วเพื่อเป็นคำตอบใหม่เพื่อที่ฉันจะได้เห็นว่าทำไมถึงมีคนโหวตให้ บางทีฉันอาจจะพลาดอะไรบางอย่างที่นี่เช่นกัน?
Mark McCorkle

2
ใช่ฉันไม่ใช้initWithTitle:@"Done"ฉันใช้initWithBarButtonSystemItem:UIBarButtonSystemItemDoneแทน สิ่งนี้จะส่งคืนปุ่มแถบเสร็จสิ้นของ Apple มาตรฐาน นอกจากนี้จะมีการแปลแล้ว
Andrey Gordeev

3
ควรเพิ่มสิ่งนี้เป็นการปรับปรุง (ความคิดเห็น) สำหรับคำตอบที่ถูกต้องก่อนหน้านี้ IMO หรือคาดหวังการโหวต คำตอบใหม่ควรเกี่ยวข้องกับแนวทางที่แตกต่างไปจากคำถามเดิมไม่ใช่การปรับปรุงคำถามที่มีอยู่ อย่างไรก็ตามขอขอบคุณสำหรับการปรับปรุง ;-)
Mark McCorkle

4
ไม่ฉันไม่คิดอย่างนั้น ไม่ควรใช้ความคิดเห็นในการเขียนโค้ด :)
Andrey Gordeev

13

เพียงแค่สร้างคำตอบข้างต้นด้วยเวอร์ชัน Swift เนื่องจากฉันต้องแปล:

   @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

คุณสามารถใช้ได้

myTextField.inputAccessoryView = _inputView;

มุมมองอุปกรณ์เสริมสำหรับป้อนข้อมูลเป็นมุมมองที่อยู่เหนือแป้นพิมพ์เสมอและปิดด้วย [textfield resignFirstResponder]

วางไว้doneเหนือมุมมองอินพุตและดำเนินการตอบกลับก่อนลาออกของฟิลด์ข้อความ



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

ฉันใช้คำตอบของคุณคล้ายกับสิ่งที่ฉันต้องทำ ขอบคุณ. แต่ปุ่มไม่ได้มาเป็นวัตถุเคลื่อนไหวเมื่อแสดงแป้นพิมพ์
Arpit B Parekh

1

คุณจำเป็นต้องตรวจสอบว่าคุณกำลังใช้โทรศัพท์หรือ iPad เนื่องจาก iPad ใช้ปุ่มย้อนกลับบนแป้น "หมายเลข"


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.