Domanda

Sto lavorando su un app iPad utilizzando 3.2 SDK. Ho a che fare con l'ottenimento delle dimensioni della tastiera per evitare che i miei campi di testo da nascondono dietro di esso.

Ricevo un avviso in Xcode -?> UIKeyboardBoundsUserInfoKey è deprecato cosa devo Non utilizzare invece per ottenere l'avviso

È stato utile?

Soluzione

Ho giocato con la soluzione precedentemente offerto, ma ancora avuto problemi. Ecco quello che mi è venuta, invece:

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

Altri suggerimenti

Da documentazione per UIKeyboardBoundsUserInfoKey:

  

La chiave per un oggetto NSValue contenente un CGRect che identifica i limiti rettangolo della tastiera in coordinate finestra. Questo valore è sufficiente per ottenere la dimensione della tastiera. Se si desidera ottenere l'origine della tastiera sullo schermo (prima o dopo l'animazione) utilizzare i valori ottenuti dal dizionario informazioni utente attraverso le costanti UIKeyboardCenterBeginUserInfoKey o UIKeyboardCenterEndUserInfoKey. Con il tasto UIKeyboardFrameBeginUserInfoKey o UIKeyboardFrameEndUserInfoKey posto.

Apple raccomanda l'attuazione di una routine di convenienza di questo tipo (che potrebbero essere attuate come categoria aggiunta a UIScreen):

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

per recuperare proprietà dimensioni dei fotogrammi tastiera window-regolata.

ho preso un approccio diverso, che consiste nel verificare l'orientamento del dispositivo:

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

È sufficiente utilizzare questo codice:

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

I seguenti correzioni di codice un problema nel di Jay risposta , che presuppone che UIKeyboardWillShowNotification non scatta di nuovo quando la tastiera è già presenti.

Quando la tipizzazione con il / tastiera cinese giapponese, IOS genera un UIKeyboardWillShowNotification supplementare con il nuovo telaio tastiera anche se la tastiera è già presente, portando l'altezza del self.textView essere ridotta una seconda volta nel codice originale.

Questo riduce self.textView a quasi nulla. Diventa quindi impossibile per recuperare da questo problema in quanto ci sarà solo aspettare un singolo UIKeyboardWillHideNotification la prossima volta che la tastiera è respinto.

Invece di sottrarre / aggiungere altezza per self.textView seconda che la tastiera è mostrata / nascosta come nel codice originale, il seguente codice appena calcola l'altezza massima possibile per self.textView dopo aver sottratto l'altezza della tastiera sullo schermo.

Questo presuppone che self.textView è supponiamo per riempire l'intera vista del controller della vista, e non c'è altra visualizzazione secondaria che deve essere visibile.

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

}

Inoltre, non dimenticare di registrare le notifiche della tastiera in viewDidLoad:

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

Informazioni sulla divisione del codice di ridimensionamento in due parti

Il motivo per cui il ridimensionamento textView codice è diviso in due parti (resizeTextViewWithKeyboardNotification: e resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:) è di fissare un altro problema quando i persiste tastiera attraverso una trasmissione da un controllore vista all'altra (vedere Come faccio a rilevare la tastiera iOS quando rimane tra controllori? ).

Poiché la tastiera è già presente prima che il controllore visualizzazione viene spinto, non c'è nessuna notifica tastiera aggiuntivi vengono generati dal IOS, e quindi non c'è modo per ridimensionare il textView basato su tali notifiche tastiera.

Il codice sopra (così come il codice originale) che ridimensiona self.textView sarà quindi solo lavoro quando viene mostrata la tastiera dopo la vista è stato caricato.

La mia soluzione è quella di creare un Singleton che memorizza le ultime coordinate da tastiera, e sul - viewDidAppear: del viewController, chiamata:

- (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 è il mio Singleton qui. Idealmente dovremmo chiamare questo - viewWillAppear:, tuttavia nella mia esperienza (almeno su iOS 6), il metodo convertRect:fromView: che dobbiamo utilizzare in resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: non converte correttamente la tastiera cornice alle coordinate vista prima la vista è completamente visibile.

Basta usare il tasto UIKeyboardFrameBeginUserInfoKey o UIKeyboardFrameEndUserInfoKey invece di UIKeyboardBoundsUserInfoKey

@ Jason, è il codice se bene, tranne per un punto.

Al momento non sono in realtà animando nulla e la vista sarà semplicemente `pop' al suo nuovo size.height.

È necessario specificare uno stato da cui partire per animare. L'animazione è una sorta di (da stato) -. Cosa> (allo stato)

Fortunatamente esiste un metodo molto conveniente per specificare lo stato attuale della vista come (dallo stato).

[UIView setAnimationBeginsFromCurrentState:YES];

Se si aggiunge che la linea subito dopo beginAnimations: contesto: il codice funziona perfettamente.

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

La sua funzionava così

Questo è il vincolo della Sava fondo pulsante

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

All'interno 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

Questa è le funzioni di cui abbiamo bisogno

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()
    })
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top