So fügen Sie der Numpad-Tastatur in iOS eine Schaltfläche "Fertig" hinzu

84

Daher verfügt die Numpad-Tastatur standardmäßig nicht über die Schaltfläche "Fertig" oder "Weiter", daher möchte ich eine hinzufügen. In iOS 6 und darunter gab es einige Tricks, um der Tastatur eine Schaltfläche hinzuzufügen, aber sie scheinen in iOS 7 nicht zu funktionieren.

Zuerst abonniere ich die Tastatur mit der Benachrichtigung

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

Dann versuche ich, eine Schaltfläche hinzuzufügen, wenn die Tastatur angezeigt wird:

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

Die for-Schleife wird jedoch nicht ausgeführt, da keine Unteransichten gefunden werden. Irgendwelche Vorschläge? Ich konnte keine Lösung für iOS7 finden. Gibt es eine andere Möglichkeit, wie ich das tun soll?

Bearbeiten: Danke für all die Vorschläge für Symbolleisten, aber ich würde diesen Weg lieber nicht gehen, da ich ziemlich platzarm bin (und es ist irgendwie hässlich).

George McKibbin
quelle
Versucht diesen Beitrag? neoos.ch/blog/…
Anil
@Anil Diese Art der Anpassung von UIKeyboard ist von Apple verboten.
βhargavḯ
Überprüfen Sie mit UIKeyboardDidShowNotification.
Praveen Matanam
Versuchen Sie dies github.com/simonbs/BSKeyboardControls
the1pawan
2
Ich möchte nicht wirklich eine Symbolleiste hinzufügen, sondern die Schaltfläche direkt auf der Tastatur platzieren.
George McKibbin

Antworten:

26

Dies ist eine einfache Möglichkeit, eine fertige Schaltfläche in der iOS7-Zehnertastatur zu projizieren. Fügen Sie in der folgenden Delegate-Methode von UITextField eine Benachrichtigung für die Tastaturshow hinzu.

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

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

Implementieren Sie nun die Methode keyboardWillShowwie folgt. Hier müssen wir besonders auf iOS7 achten.

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

Fügen Sie dieses Makro nun zu einem geeigneten Header hinzu, um SYSTEM_VERSION zu erkennen

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

Balram Tiwari
quelle
1
Danke, das wollte ich :) Leider Wenn bereits eine Tastatur auf dem Bildschirm war und Sie dann zu einem Feld wechseln, das eine Numpad-Tastatur benötigt, wird keyBoardWillShow nicht aufgerufen. Aber danke, ein Schritt in die richtige Richtung, haha.
George McKibbin
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO warum nicht NSFoundationVersionNumber> NSFoundationVersionNumber_iOS_6_0? Und ich teste es, NSFoundationVersionNumber_iOS_5_0 ist besser
govo
dispatch_async ist hier nicht die zuverlässigste Methode, um sich in die Tastatur zu hacken. :(
Ben Sinclair
7
In iOS8 wird diese Schaltfläche "Fertig" nicht ausgeblendet. Nach dem Entlassen der Tastatur.
Hemant Chittora
2
Diese Antwort, wenn auch klug, musste brechen.
SwiftArchitect
187

Der viel sicherere Ansatz ist die Verwendung eines UIToolBarmit DoneButton als inputAccessoryView.


Beispielcode :

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;

Ihre -doneClickedMethode sollte folgendermaßen aussehen:

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

Beispielcode 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

Ihre -doneClickedMethode sollte folgendermaßen aussehen:

func doneClicked(sender: AnyObject) {
  self.view.endEditing(true)
}
Bhavin
quelle
Möglicherweise muss ich das am Ende tun. Mir gefällt nicht wirklich, wie viel Platz es einnimmt.
George McKibbin
3
@GeorgeMcKibbin: Der Speicherplatz sollte hier nicht das Problem sein, da dieser Speicherplatz nur während der Eingabe belegt wird. Meiner Meinung nach ist dieser Ansatz weitaus besser, als die Tastatur durcheinander zu bringen, die Apple normalerweise nicht mag.
Bhavin
Wenn ich das mache, bekomme ich nur die Symbolleiste ganz unten auf meinem Bildschirm und die Tastatur wird nicht mehr angezeigt. Gedanken?
Chris
Gute Antwort, nur ein Leckerbissen, arrayWithObjects wird unausgesprochen zugunsten von Literalen abgelehnt: [NSArray arrayWithObjects: doneButton, nil] => @ [doneButton]
Austin,
1
von iOS 8.0 UIBarButtonItemStyleBorderedist veraltete Verwendung UIBarButtonItemStyleDoneoderUIBarButtonItemStylePlain
Nazir
131

Noch einfacher:

Swift 3.0 und höher :

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 und niedriger :

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
}

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

BEARBEITEN:

Ich habe eine nützliche Bibliothek namens DCKit erstellt , in der die Symbolleiste bereits sofort verfügbar ist:

Fertig Symbolleiste über der Tastatur in iOS (bei Verwendung der DCKit-Bibliothek)

Es hat auch viele andere coole Funktionen.

Andrey Gordeev
quelle
1
Es sieht so aus, als hätten Sie Bhavins Antwort von vor einem Jahr als neue Antwort einen Flex-Bar-Button hinzugefügt, damit ich sehen kann, warum jemand abgelehnt hat. Vielleicht habe ich auch hier etwas verpasst?
Mark McCorkle
2
Ja, ich benutze nicht initWithTitle:@"Done", ich benutze initWithBarButtonSystemItem:UIBarButtonSystemItemDonestattdessen. Dadurch wird die Standard-Schaltfläche "Fertig" von Apple zurückgegeben. Außerdem wird es bereits lokalisiert sein
Andrey Gordeev
3
Dies sollte als Verbesserung (Kommentar) zur zuvor korrekten Antwort IMO hinzugefügt werden oder mit Abstimmungen rechnen. Eine neue Antwort sollte eine andere Herangehensweise an die ursprüngliche Frage beinhalten, keine Verbesserung einer bestehenden Frage. Trotzdem vielen Dank für die Verbesserung. ;-)
Mark McCorkle
4
Nein, das glaube ich nicht. Kommentare dürfen nicht zum Schreiben von Code verwendet werden :)
Andrey Gordeev
13

Bauen Sie einfach auf den obigen Antworten mit der Swift-Version auf, da ich sie übersetzen musste:

   @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)
    }
Arnaud
quelle
3

Sie können verwenden

myTextField.inputAccessoryView = _inputView;

Die Eingabezubehöransicht ist eine Ansicht, die immer über die Tastatur angezeigt wird und mit der Option geschlossen wird [textfield resignFirstResponder]

stellt doneden Eingang Blick auf und resignfirst responder die Textfelder durchzuführen.

Himanshu Gupta
quelle
2

Benutz einfach

yourTextField.inputAccessoryView

hoffe du hilfst

alvarodoune
quelle
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]; 
}
loloa
quelle
Ich habe Ihre Antwort sehr ähnlich umgesetzt, wie ich es tun muss. Vielen Dank. Die Schaltfläche wird jedoch nicht als animiertes Objekt angezeigt, wenn die Tastatur angezeigt wird.
Arpit B Parekh
1

Sie müssen erkennen, ob Sie sich auf einem Telefon oder iPad befinden, da das iPad eine Eingabetaste auf dem Nummernblock implementiert

user3288300
quelle