Richten Sie programmgesteuert eine Symbolleiste oben auf der iPhone-Tastatur aus

94

In einigen Fällen möchte ich oben auf der iPhone-Tastatur eine Symbolleiste hinzufügen (wie beispielsweise in iPhone Safari, wenn Sie durch Formularelemente navigieren).

Derzeit spezifiziere ich das Rechteck der Symbolleiste mit Konstanten. Da sich jedoch andere Elemente der Benutzeroberfläche im Fluss befinden - Symbolleisten und Navigationsleisten am oberen Bildschirmrand -, wird die Symbolleiste bei jeder geringfügigen Änderung der Benutzeroberfläche nicht mehr richtig ausgerichtet.

Gibt es eine Möglichkeit, die Position der Tastatur in Bezug auf die aktuelle Ansicht programmgesteuert zu bestimmen?

Rob Drimmie
quelle

Antworten:

142

Ab iOS 3.2 gibt es eine neue Möglichkeit, diesen Effekt zu erzielen:

UITextFieldsund UITextViewshaben eine inputAccessoryViewEigenschaft, die Sie auf jede Ansicht einstellen können, die automatisch oben angezeigt und mit der Tastatur animiert wird.

Beachten Sie, dass sich die von Ihnen verwendete Ansicht weder an anderer Stelle in der Ansichtshierarchie befinden sollte, noch dass Sie sie einer Übersicht hinzufügen sollten. Dies wird für Sie erledigt.

Tonklon
quelle
Lass es mich versuchen . Obwohl es am besten aussieht.
Harshalb
Beeindruckend. Was für ein Fund! Danke (ich habe es auf die harte
Tour gemacht
1
Ich habe eine UIToolbar mit einem UITextField in einem der Balkenschaltflächenelemente, aber obwohl ich die textFields inputAccessoryView beim ersten Drücken auf diese Symbolleiste gesetzt habe, wird die Symbolleiste nach oben verschoben, aber es wird keine Tastatur angezeigt. Beim zweiten Drücken erscheint die Tastatur mit der Symbolleiste. Haben Sie eine Idee davon?
Ugur Kumru
Aber wie man eine Symbolleiste auf UIWebView hinzufügt? :(
Dmitry
Ich habe es getan, indem ich Schaltflächen in der Standard-UIWebView-Symbolleiste ersetzt habe (der gleiche Code wie zum Entfernen).
Dmitry
72

Also im Grunde genommen:

In der init-Methode:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];

Und dann haben Sie die oben genannten Methoden, um die Position des Balkens anzupassen:

-(void) keyboardWillShow:(NSNotification *) note
{
    CGRect r  = bar.frame, t;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
    r.origin.y -=  t.size.height;
    bar.frame = r;
}

Könnte es hübsch machen, indem die Positionsänderung durch Einwickeln animiert wird

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
//...
    [UIView commitAnimations];

quelle
Ich habe mich heute Morgen in meinen alten Sachen umgesehen und festgestellt, dass dies eine viel bessere und umfassendste Antwort ist. Vielen Dank!
Rob Drimmie
Diese Antwort ist auch ein Jahr später noch ziemlich relevant. Es hat mir geholfen, über den Berg zu kommen, wenn ich etwas entwickelt habe, das damit zusammenhängt.
James_womack
2
Nur eine Warnung für Leute, die jetzt über diese Frage stolpern: Der UIKeyboardBoundsUserInfoKey ist jetzt in iPhone OS 3.2 veraltet. Es gibt andere, ähnliche UIKeyboardFrameBeginUserInfoKey, die die gleichen Informationen geben.
Stephen Darlington
9
Es gibt noch eine bessere neue Möglichkeit, dies in iOS3.2 mit der Eigenschaft inputAccessoryView für UITextField und UITextView zu tun.
Tonklon
6
Diese Antwort hat einer Menge geholfen, ist aber etwas veraltet. Sie sollten verwenden UIKeyboardFrameEndUserInfoKey, um das endgültige Bild (in Bildschirmkoordinaten) der Tastatur zu erhalten. Sie können auch die restlichen Parameter verwenden UIKeyboardAnimationDurationUserInfoKeyund UIKeyboardAnimationCurveUserInfoKeyabrufen, um sie genau an das Verhalten der Tastatur anzupassen.
Dave Peck
60

Dies basiert auf der vorhandenen Antwort von tonklon - ich füge nur ein Code-Snippet hinzu, das eine halbtransparente schwarze Symbolleiste oben auf der Tastatur sowie eine Schaltfläche "Fertig" rechts anzeigt:

UIToolbar *toolbar = [[[UIToolbar alloc] init] autorelease];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];

UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard)];

NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil];

[flexButton release];
[doneButton release];
[toolbar setItems:itemsArray];

[aTextField setInputAccessoryView:toolbar];

und das -resignKeyboardsieht aus wie:

-(void)resignKeyboard {
  [aTextField resignFirstResponder];
}

Hoffe das hilft jemandem.

Phi
quelle
2
Fügen Sie einfach einen kleinen Kommentar hinzu, um die nächste vorherige zu erhalten. UISegmentedControl * segmentControl = [[UISegmentedControl-Zuweisung] initWithItems: [NSArray arrayWithObjects: @ "Previous", @ "Next", nil]]; [segmentControl setSegmentedControlStyle: UISegmentedControlStyleBar]; [segmentControl addTarget: self action: @selector (nextPrevious :) forControlEvents: UIControlEventValueChanged];
Trausti Thor
1
Eine Ergänzung zu @ TraustiThors Kommentar: Sie müssen das segmentierte Steuerelement in ein UIBarButtonItem einschließen, um es der Symbolleiste hinzuzufügen.
Tim Büthe
Ausgezeichnet - das ist der ganze Code, den ich brauchte. Vielen Dank für die Veröffentlichung :)
Stretch
Aber was ist mit UIWebView? Wie füge ich eine Symbolleiste hinzu?
Dmitry
24

Wenn Sie sich für Tastaturbenachrichtigungen registrieren, z. B. UIKeyboardWillShowNotification UIKeyboardWillHideNotificationusw., enthält die Benachrichtigung, die Sie erhalten, die Grenzen der Tastatur in userInfodict ( UIKeyboardBoundsUserInfoKey).

Siehe die UIWindowKlassenreferenz.

amrox
quelle
16

In Version 3.0 und höher können Sie die Animationsdauer und -kurve aus dem userInfoWörterbuch der Benachrichtigungen abrufen.

Um beispielsweise die Größe der Ansicht zu animieren, um Platz für die Tastatur zu schaffen, registrieren Sie sich für die UIKeyboardWillShowNotificationund gehen Sie wie folgt vor:

- (void)keyboardWillShow:(NSNotification *)notification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];

    CGRect frame = self.view.frame;
    frame.size.height -= [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size.height;
    self.view.frame = frame;

    [UIView commitAnimations];
}

Machen Sie eine ähnliche Animation für UIKeyboardWillHideNotification.

David Beck
quelle
Sieht nach einer besseren Möglichkeit aus, dies im 3.0 SDK zu tun. Vielen Dank für die Veröffentlichung!
Hua-Ying
Danke für den Code. Das hilft sehr. Wenn ich jedoch meine UITextView so einstelle, dass sie in viewDidLoad als Ersthelfer fungiert, bewegt sich die UIToolBar nicht mit der Größenänderung der self.view. Hast du eine Idee warum?
RyanJM
1
@RyanJM: comeFirstResponder und resignFirstResponder verhalten sich seltsam, wenn die Ansicht außerhalb des Bildschirms angezeigt wird. Sie sollten stattdessen makeFirstResponder von Ihrer viewWillAppear-Methode aufrufen.
David Beck
0

Erstellen Sie diese Methode und rufen Sie sie in ViewWillLoad auf:

        - (void) keyboardToolbarSetup
{
    if(self.keyboardToolbar==nil)
        {
        self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(anyAction)];

        UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(anyOtherAction)];


        NSArray *toolbarButtons = [[NSArray alloc]initWithObjects:cancelButton,extraSpace,doneButton, nil];

        [self.keyboardToolbar setItems:toolbarButtons];

        self.myTextView.inputAccessoryView=self.keyboardToolbar;
        }
}
Juan Sebastián López
quelle
-3

Es gibt keine Möglichkeit (AFAIK), die Abmessungen der Tastaturansicht abzurufen. Es ist jedoch konstant, zumindest in jeder iPhone-Version bisher.

Wenn Sie die Position der Symbolleiste als Versatz von UNTEN Ihrer Ansicht berechnen und die Größe Ihrer Ansicht berücksichtigen, sollten Sie sich keine Sorgen machen müssen, ob eine Navigationsleiste vorhanden ist oder nicht.

Z.B

#define KEYBOARD_HEIGHT 240 // example - can't remember the exact size
#define TOOLBAR_HEIGHT 30

toolBarRect.origin.y = viewRect.size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;

// move toolbar either directly or with an animation

Anstelle einer Definition können Sie auch einfach eine keyboardHeightFunktion erstellen , die die Größe basierend auf der Anzeige der Tastatur zurückgibt, und diese Symbolleistenpositionierung in eine separate Funktion verschieben, die Ihr Layout neu organisiert.

Dies kann auch davon abhängen, wo Sie diese Positionierung vornehmen, da sich die Größe Ihrer Ansicht je nach Konfiguration der Navigationsleiste möglicherweise zwischen Laden und Anzeigen ändert. Ich glaube, der beste Ort dafür wäre viewWillAppear.

Andrew Grant
quelle
Das hat super geklappt, danke! Bisher habe ich diese Berechnung in dem von UIKeyboardDidShowNotification ausgelösten Selektor durchgeführt. Ich habe nur an einigen Stellen getestet, aber es sieht nach einem guten Ort aus.
Rob Drimmie
Ab 5.0 ist die Tastaturgröße nicht mehr statisch.
Alastair Stuart