Frage

Ich arbeite an einem iPad App 3.2 sdk. Ich bin der Umgang mit der Tastatur Größe mit dem Erhalt meiner Textfelder von Hidding hinter ihnen zu verhindern.

Ich bin eine Warnung in Xcode bekommen -> UIKeyboardBoundsUserInfoKey ist veraltet, was soll ich verwenden, anstatt diese Warnung nicht zu bekommen

War es hilfreich?

Lösung

Ich spielte mit der bisher angebotenen Lösung, aber immer noch Probleme hatte. Hier ist, was ich kam mit statt:

    - (void)keyboardWillShow:(NSNotification *)aNotification {
    [self moveTextViewForKeyboard:aNotification up:YES];
}

    - (void)keyboardWillHide:(NSNotification *)aNotification {
        [self moveTextViewForKeyboard:aNotification up:NO]; 
    }

- (void) moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{
NSDictionary* userInfo = [aNotification userInfo];

// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;

CGRect keyboardEndFrame;

[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];


[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];


// Animate up or down
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];

CGRect newFrame = textView.frame;
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];

newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1);
textView.frame = newFrame;

[UIView commitAnimations];
}

Andere Tipps

Von der Dokumentation UIKeyboardBoundsUserInfoKey:

  

Der Schlüssel für ein Objekt einen NSValue CGRect enthält, dass identifiziert die Grenzen Rechteck der Tastatur in Fensterkoordinaten. Dieser Wert ist ausreichend, um die Größe der Tastatur zu erhalten. Wenn Sie den Ursprung der Tastatur auf dem Bildschirm erhalten möchten (vor oder nach der Animation) verwenden, um die Werte aus der Benutzer-Info Wörterbuch durch die Konstanten UIKeyboardCenterBeginUserInfoKey oder UIKeyboardCenterEndUserInfoKey erhalten. Verwenden Sie die UIKeyboardFrameBeginUserInfoKey oder UIKeyboardFrameEndUserInfoKey Schlüssel statt.

empfiehlt Apple eine Hilfsroutine wie diese Umsetzung (die als eine Kategorie neben UIScreen umgesetzt werden könnte):

+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view {
    UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window];
    return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil];
}

Fenster eingestellt Tastaturrahmengröße Eigenschaften erholen.

Ich nahm einen anderen Ansatz, der die Ausrichtung des Geräts Überprüfung beinhaltet:

CGRect _keyboardEndFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;

Sie einfach diesen Code verwenden:

//NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
//instead of Upper line we can use either next line or nextest line.
//NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];

Die folgenden Code korrigiert einen Fehler in Jay Antwort , die diese UIKeyboardWillShowNotification geht davon wird nicht wieder ausgelöst wird, wenn die Tastatur bereits vorhanden ist.

Bei der Eingabe mit der japanischen / chinesischen Tastatur, feuert iOS eine zusätzliche UIKeyboardWillShowNotification mit dem neuen Tastaturrahmen, obwohl die Tastatur bereits vorhanden ist, was zu der Höhe des self.textView ein zweites Mal in dem ursprünglichen Code reduziert werden.

Dies reduziert self.textView auf fast nichts. Es dann unmöglich wird von diesem Problem zu erholen, da wir nur eine einzige UIKeyboardWillHideNotification das nächste Mal, wenn die Tastatur des Feldes verwiesen erwarten wird.

Statt Subtrahieren / Hinzufügen Höhe self.textView je nachdem, ob die Tastatur ein- / ausgeblendet, wie im ursprünglichen Code, der folgende Code berechnet nur die maximal mögliche Höhe für self.textView nach der Höhe der Tastatur auf dem Bildschirm subtrahiert wird.

Dies setzt voraus, dass self.textView ist angenommen, die gesamte Ansicht des View-Controllers zu füllen, und es gibt keine andere subview dass Bedürfnisse sichtbar sein.

- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif {

    NSDictionary* userInfo = [notif userInfo];
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardFrameInWindowsCoordinates;

    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates];

    [self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates
                             withAnimationDuration:animationDuration
                                    animationCurve:animationCurve];

}

- (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates
                           withAnimationDuration:(NSTimeInterval)duration
                                  animationCurve:(UIViewAnimationCurve)curve
{

    CGRect fullFrame = self.view.frame;

    CGRect keyboardFrameInViewCoordinates =
    [self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil];

    // Frame of the keyboard that intersects with the view. When keyboard is
    // dismissed, the keyboard frame still has width/height, although the origin
    // keeps the keyboard out of the screen.
    CGRect keyboardFrameVisibleOnScreen =
    CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates);

    // Max frame availble for text view. Assign it to the full frame first
    CGRect newTextViewFrame = fullFrame;

    // Deduct the the height of any keyboard that's visible on screen from
    // the height of the text view
    newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height;

    if (duration)
    {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:duration];
        [UIView setAnimationCurve:curve];
    }

    // Adjust the size of the text view to the new one
    self.textView.frame = newTextViewFrame;

    if (duration)
    {
        [UIView commitAnimations];
    }

}

Auch vergessen Sie nicht, die Tastatur-Benachrichtigungen in viewDidLoad zu registrieren:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter];

    [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil];
    [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil];
}

Über Aufspaltung der Größenänderung Code in zwei Teile

Der Grund, warum die Textview-Code Ändern der Größe in zwei Teile geteilt ist (resizeTextViewWithKeyboardNotification: und resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:) ist ein weiteres Problem zu beheben, wenn die Tastatur hält über einen Push von einem View-Controller zu einem anderen (siehe Wie erkenne ich die iOS-Tastatur, wenn es oben bleibt zwischen Controller? ).

Da die Tastatur bereits vorhanden ist, bevor der View-Controller gedrückt wird, gibt es keine zusätzliche Tastatur-Benachrichtigungen von iOS erzeugt wurde und somit keine Möglichkeit, die textView, um die Größe auf der Grundlage dieser Tastatur Benachrichtigungen.

Der obige Code (wie auch der ursprüngliche Code), die self.textView ändert die Größe wird also nur funktionieren, wenn die Tastatur angezeigt wird nach die Ansicht geladen ist.

Meine Lösung ist ein Singleton zu erstellen, dass speichert die letzten Tastatur Koordinaten und auf - viewDidAppear: des Viewcontroller, Aufruf:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Resize the view if there's any keyboard presence before this
    // Only call in viewDidAppear as we are unable to convertRect properly
    // before view is shown
    [self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame]
                         withAnimationDuration:0
                                animationCurve:0];
}

UASKeyboard ist mein Singleton hier. Im Idealfall sollten wir dies in - viewWillAppear: nennen, aber meiner Erfahrung nach (zumindest auf iOS 6), die convertRect:fromView: Methode, dass wir auf den Einsatz in resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: muss nicht ordnungsgemäß den Tastaturrahmen auf die Ansicht Koordinaten konvertiert werden, bevor die Ansicht vollständig sichtbar ist.

Verwenden Sie einfach die UIKeyboardFrameBeginUserInfoKey oder UIKeyboardFrameEndUserInfoKey Schlüssel statt UIKeyboardBoundsUserInfoKey

@ Jason, Sie Code, wenn in Ordnung, außer für einen Punkt.

Im Moment sind Sie nicht wirklich etwas zu animieren und die Aussicht einfach `Pop‘ zu seinem neuen Size.height.

Sie haben, von denen belebten einen Zustand angeben. Eine Animation ist eine Art (von Staat.) -> (zum Zustand) Sache

Zum Glück gibt es eine sehr bequeme Methode den aktuellen Stand der Ansicht, als die (vom Staat) angeben.

[UIView setAnimationBeginsFromCurrentState:YES];

Wenn Sie diese Zeile direkt nach beginAnimations hinzufügen: Kontext: Ihr Code funktioniert perfekt.

- (CGSize)keyboardSize:(NSNotification *)aNotification {
    NSDictionary *info = [aNotification userInfo];
    NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    CGSize keyboardSize;
    if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) {
        _screenOrientation = orientation;
        if (UIDeviceOrientationIsPortrait(orientation)) {
            keyboardSize = [beginValue CGRectValue].size;
        } else {
            keyboardSize.height = [beginValue CGRectValue].size.width;
            keyboardSize.width = [beginValue CGRectValue].size.height;
        }
    } else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) {
        // We didn't rotate
        if (_screenOrientation == orientation) {
            if (UIDeviceOrientationIsPortrait(orientation)) {
                keyboardSize = [beginValue CGRectValue].size;
            } else {
                keyboardSize.height = [beginValue CGRectValue].size.width;
                keyboardSize.width = [beginValue CGRectValue].size.height;
            }
        // We rotated
        } else if (UIDeviceOrientationIsPortrait(orientation)) {
            keyboardSize.height = [beginValue CGRectValue].size.width;
            keyboardSize.width = [beginValue CGRectValue].size.height;
        } else {
            keyboardSize = [beginValue CGRectValue].size;
        }
    }


    return keyboardSize;
}

Das funktionierte wie diese

Dies ist die Einschränkung der Schaltfläche Speichern unten

@IBOutlet weak var saveBtnBottom: NSLayoutConstraint!
@IBOutlet weak var nameText: UITextField!

Innerhalb viewDidLoad

NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
nameText.delegate = self

Dies ist die Funktionen, die wir brauchen

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    nameText.resignFirstResponder()
    return true
}


@objc func keyBoardWillShow(notification: Notification){
    if let userInfo = notification.userInfo as? Dictionary<String, AnyObject>{
        let frame = userInfo[UIResponder.keyboardFrameEndUserInfoKey]
        let keyBoardRect = frame?.cgRectValue
        if let keyBoardHeight = keyBoardRect?.height {
            self.saveBtnBottom.constant = keyBoardHeight 

            UIView.animate(withDuration: 0.5, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }
}

@objc func keyBoardWillHide(notification: Notification){
    self.saveBtnBottom.constant = 30.0
    UIView.animate(withDuration: 0.5, animations: {
        self.view.layoutIfNeeded()
    })
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top