Domanda

Ho un app dove, in Interface Builder , ho istituito un UIView che ha un campo di testo nella parte inferiore della vista. Quando eseguo l'applicazione e cerco di inserire il testo in quel campo, la tastiera scivola overtop del campo, quindi non posso vedere quello che sto scrivendo fino a quando ho nascondere nuovamente la tastiera.

Qualcun altro ha eseguito in questo problema e ha trovato un buon modo per risolverlo senza né rendere la vista padre scorrevole o lo spostamento del campo di testo più in alto dello schermo?

È stato utile?

Soluzione

La soluzione più comune è quello di far scorrere il campo (e tutto sopra di esso) con un'animazione, e poi di nuovo verso il basso quando si è fatto. Potrebbe essere necessario mettere il campo di testo e alcuni degli altri elementi in un'altra vista e far scorrere la vista come un'unità. (Io chiamo queste cose "piatti" come in "placche tettoniche", ma che sono solo io). Ma qui è l'idea generale, se non è necessario per ottenere l'immaginazione.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self animateTextField: textField up: YES];
}


- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self animateTextField: textField up: NO];
}

- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
    const int movementDistance = 80; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

    int movement = (up ? -movementDistance : movementDistance);

    [UIView beginAnimations: @"anim" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];
    self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    [UIView commitAnimations];
}

Altri suggerimenti

Questo fatto miracoli per me scorrevole uitextfields

In particolare si ha il vantaggio di calcolare la distanza diapositiva di animazione a seconda della posizione del campo di testo.

IQKeyboardManager fare questo per voi con NO riga di codice , solo bisogno di trascinare e rilasciare file sorgente relativo a progetto. IQKeyboardManager supportare anche orientamento del dispositivo , Automatic UIToolbar Gestione , keyboardDistanceFromTextField e molto di più di quanto si pensi.

entrare descrizione dell'immagine qui

Ecco il diagramma di flusso di controllo: Flow Chart Control

Step1: - Aggiunto notifiche globali di UITextField, UITextView, e UIKeyboard in una classe Singleton. L'ho chiamato IQKeyboardManager .

Fase 2: - Se trovate notifiche UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotification o UITextViewTextDidBeginEditingNotification, quindi cercare di ottenere esempio topMostViewController dalla gerarchia UIWindow.rootViewController. Al fine di scoprire correttamente UITextField / UITextView su esso, telaio di topMostViewController.view deve essere regolata.

Fase 3: -. Calcolato distanza di movimento atteso di topMostViewController.view rispetto al primo risposto UITextField / UITextView

Fase 4: -. topMostViewController.view.frame spostato su / giù a seconda della distanza di movimento atteso

Fase 5: -. Se trovato UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification o notifica UITextViewTextDidEndEditingNotification, poi di nuovo cercare di ottenere esempio topMostViewController dalla gerarchia UIWindow.rootViewController

Fase 6: -. la distanza calcolata disturbato di topMostViewController.view che deve essere riportato alla sua posizione originale

Step7: -. topMostViewController.view.frame Restaurata in funzione della distanza disturbato

Step8: - IQKeyboardManager istanza di classe del carico app, in modo ogni UITextField / UITextView in app si regola automaticamente in base alla distanza di movimento previsto.

Questo è tutto

Per espandere l'Amagrammer risposta, qui è una lezione di prova:

LoginViewController.h

@interface LoginViewController : UIViewController <UITextFieldDelegate> {

}

@property (nonatomic, retain) IBOutlet UITextField    *emailTextField;
@property (nonatomic, retain) IBOutlet UITextField    *passwordTextField;

Avviso stiamo attuando il "UITextFieldDelegate"

LoginViewController.m

@implementation LoginViewController
@synthesize emailTextField=_emailTextField;
@synthesize passwordTextField=_passwordTextField;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        //Register to receive an update when the app goes into the backround
        //It will call our "appEnteredBackground method
        [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appEnteredBackground)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    }
    return self;
}


- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
    const int movementDistance = 80; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

    int movement = (up ? -movementDistance : movementDistance);

    [UIView beginAnimations: @"anim" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];
    self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    [UIView commitAnimations];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self animateTextField: textField up: YES];
}


- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self animateTextField: textField up: NO];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}
//This is called when the app goes into the background.
//We must reset the responder because animations will not be saved
- (void)appEnteredBackground{
    [self.emailTextField resignFirstResponder];
    [self.passwordTextField resignFirstResponder];
}

Come circa la soluzione ufficiale: contenuto che si trova sotto la tastiera Moving

  

Regolazione suo sito web in genere comporta temporaneamente uno o ridimensionamento   più viste e posizionandoli in modo che resti oggetto testo   visibile. Il modo più semplice per gestire oggetti di testo con la tastiera è   nell'incorporarli all'interno di un oggetto UIScrollView (o una delle sue sottoclassi   come UITableView). Quando viene visualizzata la tastiera, tutto quello che hanno a che fare   è ripristinare l'area del contenuto della vista di scorrimento e scorrere la desiderata   oggetto di testo in posizione. Così, in risposta ad un   UIKeyboardDidShowNotification, il vostro metodo del gestore farebbe il   seguenti:

     
      
  1. Ottenere la dimensione della tastiera.
  2.   
  3. Regolare il contenuto riquadro inferiore del vostro vista di scorrimento per la tastiera   di altezza.
  4.   
  5. Scorrere il campo di testo di destinazione in vista.
  6.   
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];

   [[NSNotificationCenter defaultCenter] addObserver:self
             selector:@selector(keyboardWillBeHidden:)
             name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

Ho affrontare lo stesso problema nelle cellule UITableView TextField. Risolvo questo problema implementando seguente metodo per ascoltare la notifica della tastiera.

Observer per le notifiche qui:

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

gestire tali notifiche utilizzando la funzione di seguito:

(void)keyboardWasShown:(NSNotification*)aNotification 
(void)keyboardWillBeHidden:(NSNotification*)aNotification 

Check this out. Nessun problema per voi.

Questa soluzione è molto ordinato. Tutto quello che dovete fare è aggiungere i vostri campi di testo in un UIScrollView e cambiare categoria per TPKeyboardAvoidingScollView, se si utilizza storyboard. La vista di scorrimento è estesa in modo tale che sarebbe rilevare quando la tastiera è visibile e spostarsi sopra la tastiera a distanza ragionevole. E 'la soluzione perfetta perché la sua autonoma della vostra UIViewController. Ogni cosa necessaria è fatto all'interno della classe di cui sopra. Grazie Michael Tyson et all.

TPKeyboardAvoiding

Di seguito è una versione veloce di risposta di Amagrammer. Inoltre, una variazione utilizzando l'evento UIKeyboardWillShowNotification da quando avevo bisogno di conoscere la dimensione tastiere prima di spostare la vista fuori strada.

var keyboardHeight:CGFloat = 0

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChange:", name: UIKeyboardWillShowNotification, object: nil)
}

func textFieldDidBeginEditing(textField: UITextField) {
    //keyboardWillChange (below) is used instead of textFieldDidBeginEditing because textFieldDidBeginEditing
    //is called before the UIKeyboardWillShowNotification necessary to determine the keyboard height.
}

func textFieldDidEndEditing(textField: UITextField) {
    animateTextField(false)
}

func animateTextField(textFieldUp:Bool) {
    let movementDistance:CGFloat = keyboardHeight
    let movementDuration = 0.3

    let movement:CGFloat = (textFieldUp ? -movementDistance : movementDistance)

    UIView.beginAnimations("anim", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration)
    self.view.frame = CGRectOffset(self.view.frame, 0, movement)
    UIView.commitAnimations()
}

func keyboardWillChange(notification:NSNotification) {
    let keyboardRect:CGRect = ((notification.userInfo![UIKeyboardFrameEndUserInfoKey])?.CGRectValue)!
    keyboardHeight = keyboardRect.height
    animateTextField(true)
}

C'era una grande walkthrough a editing textfields senza oscurare (link morto, ecco un link Wayback: https://web.archive.org/web/20091123074029/http://acts-as-geek.blogspot.com/2009 /11/editing-textfields-without-obscuring.html ). Essa mostra come spostare un UIView esistente su un UIScrollView, e per far scorrere automaticamente quando viene visualizzata la tastiera.

Ho aggiornato un po 'per calcolare l'altezza corretta per il UIScrollView quando ci sono controlli (ad esempio un UITabBar) al di sotto del UIScrollBar. Vedere dopo l'aggiornamento UIView .

Ecco una soluzione che utilizza Xcode5, iOS7:

Utilizzare i blocchi UITextFieldDelegate e di animazione.

Questo è quasi tutto il codice per il ViewController ma ho voluto includere il codice delegato per quelli ancora in qualche modo non hanno familiarità con il modello di delegato (come me). Ho incluso anche il codice per nascondere la tastiera quando si tocca lontano dalla TextView.

È possibile spostare il punto di vista (pulsanti, i TextField, ecc) più in alto vuoi solo fare in modo di mettere al loro posto (+100 poi -100).

@interface ViewController () <UITextFieldDelegate>
@property (strong, nonatomic) IBOutlet UITextField *MyTextField;

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.MyTextField.delegate = self;

}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
      NSLog(@"text began editing");

      CGPoint MyPoint = self.MyTextField.center;

      [UIView animateWithDuration:0.3
                    animations:^{

                    self.MyTextField.center = CGPointMake(MyPoint.x, MyPoint.y - 100);
                                }];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
     NSLog(@"text ENDED editing");

     CGPoint MyPoint = self.MyTextField.center;

     [UIView animateWithDuration:0.3
                 animations:^{

     self.MyTextField.center = CGPointMake(MyPoint.x, MyPoint.y + 100);
                             }];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     [self.view endEditing:YES];
}

Credo che un modo potrebbe essere quello di spostare la vostra posizione vista tutta da (x, y) (x, y-keybaardHeight) quando il campo di testo viene cliccato e rimetterlo quando la tastiera è respinto, potrebbe apparire un po 'strano come la vista appena arriva (forse andrei essere male se si animarla).

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    CGRect frame=self.view.frame;
    frame.origin=CGPointMake(x...//set point here
    self.view.frame=frame;
}

In aggiunta alla soluzione di Amagrammer, se si utilizza cocos2d in modalità verticale modificare questa riga:

self.view.frame = CGRectOffset(self.view.frame, 0, movement);

a questo:

[CCDirector sharedDirector].openGLView.frame = CGRectOffset([CCDirector sharedDirector].openGLView.frame, movement, 0);

Se si utilizza cocos2d in modalità orizzontale, apportare la modifica sopra e passare i valori up in textFieldDidBeginEditing: e textFieldDidEndEditing:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    [self animateTextField:textField up:NO];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [self animateTextField:textField up:YES];
}

Ho avuto lo stesso problema e ho trovato GTKeyboardHelper essere una facile via d'uscita.

Dopo trascinare e rilasciare il quadro nel progetto, includere il file di intestazione. Scaricare e aprire il progetto di esempio, quindi trascinare l'oggetto "della tastiera Helper" dalla sezione oggetti del XI ter alla sezione di oggetti in costruttore di interfaccia del progetto.

Trascinare e rilasciare tutti i vostri punti di vista di essere figli del "Helper tastiera".

Drag and quadro goccia che uso nei miei progetti. Supporta il licenziamento automatico quando si tocca al di fuori di un primo risponditore o quando si scorre.

GTKeyboardHelper

Basta far scorrere la vista su e giù in base alle esigenze:

- (void)textFieldDidEndEditing:(UITextField *)textField {
    self.currentTextField = nil;
    [self animateTextField: textField up: NO];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [self.currentTextField resignFirstResponder];
    return YES;
}

- (void) animateTextField:(UITextField*) textField up:(BOOL)up {
    const int movementDistance = 80; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

    int movement = (up ? -movementDistance : movementDistance);

    [UIView animateWithDuration:movementDuration animations:^{
        self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    }];
}

Non dimenticare di impostare self come UITextFieldDelegate e come il delegate textField reale.

(Grazie a Ammagrammer, questa è solo una risposta più breve utilizzando i blocchi per le animazioni)

ho qualcos'altro, se si desidera. Il punto qui è che si desidera impostare il centro tuo UIView sul campo di testo che si sta modificando.

Prima di ciò, è necessario salvare il INITIAL_CENTER , come CGPoint , dal self.view.center e INITIAL_VIEW come < strong> CGRect da self.view.frame in una proprietà const.

È possibile creare un metodo come questo:

- (void) centerOn: (CGRect) fieldFrame {

    // Set up the center by taking the original view center
    CGPoint center = CGPointMake(INITIAL_CENTER.x,
                             INITIAL_CENTER.y - ((fieldFrame.origin.y + fieldFrame.size.height/2) - INITIAL_CENTER.y));


    [UIView beginAnimations:@"centerViewOnField" context:nil];
    [UIView setAnimationDuration:0.50];

    if (CGRectEqualToRect(fieldFrame,INITIAL_VIEW)) {
        self.view.frame = INITIAL_VIEW;
        [self.view setCenter:INITIAL_CENTER];
    } else {
        [self.view setCenter:center];
    }


    [UIView commitAnimations];
}

Poi, sul UITextFieldDelegate , è necessario chiamare centerOn: (CGRect) in seguito metodi:

textFieldDidBeginEditing: (UITextField *) con, come parametro, la cornice del campo di testo che si desidera centrare.

E si deve chiamare nel vostro gestore di eventi, in cui si chiude la tastiera,

textFieldDidEndEditing: (UITextField *) può essere uno dei modi per farlo, mettendo l'INITIAL_VIEW come parametro di centerOn:. (CGRect)

Credo che sulle versioni più recenti di iOS (6.1+, forse anche prima), la vista sottostante, almeno per UITableView, auto-restringe quando la tastiera si apre. Quindi, avete solo bisogno di rendere il campo di testo visibile in quella vista. In init:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification
                                           object:nil];

quindi:

- (void)keyboardWasShown:(NSNotification*)notification
{
    // Scroll the text field into view so it's not under the keyboard.
    CGRect rect = [self.tableView convertRect:inputView.bounds fromView:inputView];
    [self.tableView scrollRectToVisible:rect animated:YES];
}

https://github.com/ZulwiyozaPutra/Shift-Keyboard-Example Spero che questa soluzione ha aiutato. Sono tutte Swift 3 scritti.

//
//  ViewController.swift
//  Shift Keyboard Example
//
//  Created by Zulwiyoza Putra on 11/23/16.
//  Copyright © 2016 Zulwiyoza Putra. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    
    
    //connecting textfield from storyboard
    @IBOutlet weak var textField: UITextField!
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        subscribeToKeyboardNotifications()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        self.textField.delegate = self
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        unsubscribeFromKeyboardNotifications()
    }
    
    //Hide keyboard after finished editing
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
    
    //Setup view before keyboard appeared
    func keyboardWillAppear(_ notification:Notification) {
        view.frame.origin.y = 0 - getKeyboardHeight(notification)
    }
    
    //Setup view before keyboard disappeared
    func keyboardWillDisappear(_ notification: Notification) {
        view.frame.origin.y = 0
    }
    
    //Getting keyboard height
    func getKeyboardHeight(_ notification:Notification) -> CGFloat {
        let userInfo = notification.userInfo
        let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
        return keyboardSize.cgRectValue.height
    }
    
    //Subscribing to notifications to execute functions
    func subscribeToKeyboardNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(_:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(_:)), name: .UIKeyboardWillHide, object: nil)
    }
    
    //Unsubscribing from notifications
    func unsubscribeFromKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
    }
    
}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top