ios Come posso far muovere UITextField quando è presente la tastiera?





15 Answers

Avevo anche un sacco di problemi con un UIScrollView componeva più UITextFields , dei quali uno o più di essi sarebbero stati oscurati dalla tastiera quando sono stati modificati.

Ecco alcune cose da considerare se il tuo UIScrollView non sta scorrendo correttamente.

1) Assicurati che contentSize sia maggiore della dimensione del frame di UIScrollView . Il modo per capire UIScrollViews è che UIScrollView è come una finestra di visualizzazione sul contenuto definito in contentSize. Quindi, per consentire a UIScrollview di scorrere ovunque, il contentSize deve essere maggiore di UIScrollView . Altrimenti, non è richiesto lo scorrimento poiché tutto ciò che è definito in contentSize è già visibile. BTW, default contentSize = CGSizeZero .

2) Ora che hai capito che UIScrollView è davvero una finestra sul tuo "contenuto", il modo per assicurarti che la tastiera non UIScrollView's "finestra" UIScrollView's visualizzazione UIScrollView's sarebbe quella di ridimensionare l' UIScrollView modo che quando la tastiera è presente, tu avere la finestra di UIScrollView dimensionata per il solo UIScrollView originale frame.size.height meno l'altezza della tastiera. Questo assicurerà che la tua finestra sia solo quella piccola area visibile.

3) Ecco il trucco: quando l'ho implementato per la prima volta ho pensato che avrei dovuto ottenere il CGRect del campo di testo modificato e chiamare UIScrollView's metodo scrollRecToVisible UIScrollView's . Ho implementato il metodo UITextFieldDelegate textFieldDidBeginEditing con la chiamata al metodo scrollRecToVisible . Questo in realtà ha funzionato con uno strano effetto collaterale che lo scorrimento avrebbe fatto scattare l' UITextField in posizione. Per molto tempo non sono riuscito a capire cosa fosse. Poi ho commentato il metodo textFieldDidBeginEditing Delegate e tutto funziona !! (???). Come si è scoperto, credo che UIScrollView UITextField implicitamente l' UITextField attualmente modificato nella finestra visibile implicitamente. La mia implementazione del metodo UITextFieldDelegate e la successiva chiamata a scrollRecToVisible era ridondante ed era la causa dello strano effetto collaterale.

Ecco quindi i passaggi per far scorrere correttamente il tuo UITextField in un UIScrollView in posizione quando appare la tastiera.

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillShow:) 
                                                 name:UIKeyboardWillShowNotification 
                                               object:self.view.window];
    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillHide:) 
                                                 name:UIKeyboardWillHideNotification 
                                               object:self.view.window];
    keyboardIsShown = NO;
    //make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
    CGSize scrollContentSize = CGSizeMake(320, 345);
    self.scrollView.contentSize = scrollContentSize;
}

- (void)keyboardWillHide:(NSNotification *)n
{
    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;


    // resize the scrollview
    CGRect viewFrame = self.scrollView.frame;
    // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
    viewFrame.size.height += (keyboardSize.height - kTabBarHeight);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];

    keyboardIsShown = NO;
}

- (void)keyboardWillShow:(NSNotification *)n
{
    // This is an ivar I'm using to ensure that we do not do the frame size adjustment on the `UIScrollView` if the keyboard is already shown.  This can happen if the user, after fixing editing a `UITextField`, scrolls the resized `UIScrollView` to another `UITextField` and attempts to edit the next `UITextField`.  If we were to resize the `UIScrollView` again, it would be disastrous.  NOTE: The keyboard notification will fire even when the keyboard is already shown.
    if (keyboardIsShown) {
        return;
    }

    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    // resize the noteView
    CGRect viewFrame = self.scrollView.frame;
    // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
    viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];
    keyboardIsShown = YES;
}
  1. Registrati per le notifiche della tastiera su viewDidLoad
  2. Annullare la registrazione per il nofitication della tastiera in viewDidUnload
  3. Assicurati che contentSize sia impostato e maggiore di UIScrollView su viewDidLoad
  4. Riduci UIScrollView quando è presente la tastiera
  5. Ripristina UIScrollView quando la tastiera si spegne.
  6. Usa un ivar per rilevare se la tastiera è già mostrata sullo schermo poiché le notifiche della tastiera vengono inviate ogni volta che un UITextField viene UITextField schede anche se la tastiera è già presente per evitare di restringere l' UIScrollView quando è già ridotto

Una cosa da notare è che UIKeyboardWillShowNotification si UIKeyboardWillShowNotification anche quando la tastiera è già sullo schermo quando si fa tabulazione su un altro UITextField . Mi sono occupato di questo utilizzando un ivar per evitare di ridimensionare UIScrollView quando la tastiera è già sullo schermo. Il ridimensionamento inavvertitamente di UIScrollView quando la tastiera è già presente sarebbe disastroso!

Spero che questo codice ti risparmi un sacco di mal di testa.

ios objective-c uitextfield uikeyboard

Con l'SDK iOS:

Ho un UIView con UITextField che fa apparire una tastiera. Ho bisogno che sia in grado di:

  1. Consentire lo scorrimento dei contenuti di UIScrollView per vedere gli altri campi di testo quando viene visualizzata la tastiera

  2. Automaticamente "salta" (scorrendo verso l'alto) o accorciando

So che ho bisogno di un UIScrollView . Ho provato a cambiare la classe del mio UIView su un UIScrollView ma non riesco ancora a scorrere le caselle di testo verso l'alto o verso il basso.

Ho bisogno sia di un UIView che di un UIScrollView ? Si va dentro l'altro?

Cosa deve essere implementato per scorrere automaticamente al campo di testo attivo?

Idealmente la maggior parte della configurazione dei componenti sarà eseguita in Interface Builder. Mi piacerebbe solo scrivere il codice per quello che serve.

Nota: l' UIView (o UIScrollView ) con cui sto lavorando viene visualizzato da una barra delle linguette ( UITabBar ), che deve funzionare normalmente.

Modifica: sto aggiungendo la barra di scorrimento solo per quando viene visualizzata la tastiera. Anche se non è necessario, mi sembra che fornisca un'interfaccia migliore perché, ad esempio, l'utente può scorrere e modificare le caselle di testo.

Ho funzionato dove cambio la dimensione del frame di UIScrollView quando la tastiera va su e giù. Sto semplicemente usando:

-(void)textFieldDidBeginEditing:(UITextField *)textField { 
    //Keyboard becomes visible
    scrollView.frame = CGRectMake(scrollView.frame.origin.x, 
                     scrollView.frame.origin.y, 
scrollView.frame.size.width,
scrollView.frame.size.height - 215 + 50);   //resize
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
   //keyboard will hide
    scrollView.frame = CGRectMake(scrollView.frame.origin.x, 
       scrollView.frame.origin.y, 
     scrollView.frame.size.width,
      scrollView.frame.size.height + 215 - 50); //resize
}

Tuttavia, questo non si sposta automaticamente verso l'alto o centra i campi di testo inferiori nell'area visibile, che è quello che mi piacerebbe davvero.




In textFieldDidBeginEditting e in textFieldDidEndEditing chiama la funzione [self animateTextField:textField up:YES] modo:

-(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 = -130; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

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

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

Spero che questo codice ti possa aiutare.

In Swift 2

func animateTextField(textField: UITextField, up: Bool) 
{
     let movementDistance:CGFloat = -130
     let movementDuration: Double = 0.3

     var movement:CGFloat = 0
     if up 
     {
         movement = movementDistance
     }
     else 
     {
         movement = -movementDistance
     }
     UIView.beginAnimations("animateTextField", context: nil)
     UIView.setAnimationBeginsFromCurrentState(true)
     UIView.setAnimationDuration(movementDuration)
     self.view.frame = CGRectOffset(self.view.frame, 0, movement)
     UIView.commitAnimations()
}


func textFieldDidBeginEditing(textField: UITextField) 
{
    self.animateTextField(textField, up:true)
}

func textFieldDidEndEditing(textField: UITextField) 
{
    self.animateTextField(textField, up:false)
}

SWIFT 3

 func animateTextField(textField: UITextField, up: Bool)
    {
        let movementDistance:CGFloat = -130
        let movementDuration: Double = 0.3

        var movement:CGFloat = 0
        if up
        {
            movement = movementDistance
        }
        else
        {
            movement = -movementDistance
        }
        UIView.beginAnimations("animateTextField", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration)
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }


    func textFieldDidBeginEditing(textField: UITextField)
    {
        self.animateTextField(textField: textField, up:true)
    }

    func textFieldDidEndEditing(textField: UITextField)
    {
        self.animateTextField(textField: textField, up:false)
    }



Per la soluzione universale , ecco il mio approccio per l'implementazione di IQKeyboardManager .

Fase 1: - Ho aggiunto notifiche globali di UITextField , UITextView e UIKeyboard in una classe singleton. Lo chiamo IQKeyboardManager .

UIKeyboardWillShowNotification 2: - Se trovato UIKeyboardWillShowNotification , UITextFieldTextDidBeginEditingNotification o UITextViewTextDidBeginEditingNotification notifiche, cerco di ottenere topMostViewController istanza topMostViewController dalla gerarchia UIWindow.rootViewController . Per scoprire correttamente UITextField / UITextView su di esso, è necessario modificare la cornice di topMostViewController.view .

Fase 3: - Ho calcolato la distanza di spostamento prevista di topMostViewController.view rispetto al primo UITextField / UITextView risposto.

Step4: - Ho spostato la vista topMostViewController.view.frame su / giù in base alla distanza di spostamento prevista.

Fase 5: - Se viene trovata la UIKeyboardWillHideNotification , UITextFieldTextDidEndEditingNotification o UITextViewTextDidEndEditingNotification , provo nuovamente a ottenere topMostViewController istanza topMostViewController dalla gerarchia UIWindow.rootViewController .

Step6: - Ho calcolato la distanza disturbata di topMostViewController.view che deve essere ripristinata nella sua posizione originale.

Fase 7: - Ho ripristinato topMostViewController.view.frame in base alla distanza disturbata.

Step8: - Ho istanziato l'istanza della classe IQKeyboardManager singleton sul caricamento dell'app, quindi ogni UITextField / UITextView nell'app si regolerà automaticamente in base alla distanza di spostamento prevista.

Questo è tutto IQKeyboardManager che IQKeyboardManager fa per te con NO LINE OF CODE davvero !! solo bisogno di trascinare e rilasciare il file sorgente relativo al progetto. IQKeyboardManager supporta anche l' orientamento del dispositivo , la gestione automatica di UIToolbar , KeybkeyboardDistanceFromTextField e molto più di quanto si pensi.




Per i programmatori Swift :

Questo farà tutto per te, basta metterli nella classe del tuo controller di visualizzazione e implementare UITextFieldDelegate sul tuo controller di visualizzazione e impostare il delegato del textField su self

textField.delegate = self // Setting delegate of your UITextField to self

Implementare i metodi di callback delegati:

func textFieldDidBeginEditing(textField: UITextField) {
    animateViewMoving(true, moveValue: 100)
}

func textFieldDidEndEditing(textField: UITextField) {
    animateViewMoving(false, moveValue: 100)
}

// Lifting the view up
func animateViewMoving (up:Bool, moveValue :CGFloat){
    let movementDuration:NSTimeInterval = 0.3
    let movement:CGFloat = ( up ? -moveValue : moveValue)
    UIView.beginAnimations( "animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration )
    self.view.frame = CGRectOffset(self.view.frame, 0,  movement)
    UIView.commitAnimations()
}



Shiun ha dichiarato: "Come si è scoperto, credo che UIScrollView implichi implicitamente l'UITextField attualmente modificato nella finestra visibile implicitamente" Questo sembra essere vero per iOS 3.1.3, ma non 3.2, 4.0 o 4.1. Ho dovuto aggiungere un scrollRectToVisible esplicito per rendere visibile UITextField su iOS> = 3.2.




developer.apple.com/library/ios/#documentation/StringsTextFonts/… documento descrive una soluzione a questo problema. Guarda il codice sorgente sotto "Spostamento del contenuto che si trova sotto la tastiera". È piuttosto semplice.

EDIT: notato che c'è un piccolo problema nell'esempio. Probabilmente vorrai ascoltare per UIKeyboardWillHideNotificationinvece di UIKeyboardDidHideNotification. In caso contrario, la vista di scorrimento dietro alla tastiera verrà ritagliata per la durata dell'animazione di chiusura della tastiera.




Piccola correzione che funziona per molti campi UIText

#pragma mark UIKeyboard handling

#define kMin 150

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
   if (currTextField) {
      [currTextField release];
   }
   currTextField = [sender retain];
   //move the main view, so that the keyboard does not hide it.
   if (self.view.frame.origin.y + currTextField.frame.origin. y >= kMin) {
        [self setViewMovedUp:YES]; 
   }
}



//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
   [UIView beginAnimations:nil context:NULL];
   [UIView setAnimationDuration:0.3]; // if you want to slide up the view

   CGRect rect = self.view.frame;
   if (movedUp)
   {
      // 1. move the view's origin up so that the text field that will be hidden come above the keyboard 
      // 2. increase the size of the view so that the area behind the keyboard is covered up.
      rect.origin.y = kMin - currTextField.frame.origin.y ;
   }
   else
   {
      // revert back to the normal state.
      rect.origin.y = 0;
   }
   self.view.frame = rect;

   [UIView commitAnimations];
}


- (void)keyboardWillShow:(NSNotification *)notif
{
   //keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately

   if ([currTextField isFirstResponder] && currTextField.frame.origin.y + self.view.frame.origin.y >= kMin)
   {
      [self setViewMovedUp:YES];
   }
   else if (![currTextField isFirstResponder] && currTextField.frame.origin.y  + self.view.frame.origin.y < kMin)
   {
      [self setViewMovedUp:NO];
   }
}

- (void)keyboardWillHide:(NSNotification *)notif
{
   //keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately
   if (self.view.frame.origin.y < 0 ) {
      [self setViewMovedUp:NO];
   }

}


- (void)viewWillAppear:(BOOL)animated
{
   // register for keyboard notifications
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) 
                                                name:UIKeyboardWillShowNotification object:self.view.window]; 
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) 
                                                name:UIKeyboardWillHideNotification object:self.view.window]; 
}

- (void)viewWillDisappear:(BOOL)animated
{
   // unregister for keyboard notifications while not visible.
   [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 
}



Non sono sicuro se spostare la vista verso l'alto sia l'approccio corretto, l'ho fatto in modo diverso, ridimensionando l'UIScrollView. L'ho spiegato nei dettagli su un piccolo article




Ci sono così tante soluzioni, ma ho passato alcune ore prima che inizi a funzionare. Quindi, metto questo codice qui (basta incollare sul progetto, non è necessario apportare alcuna modifica):

@interface RegistrationViewController : UIViewController <UITextFieldDelegate>{
    UITextField* activeField;
    UIScrollView *scrollView;
}
@end

- (void)viewDidLoad
{
    [super viewDidLoad];

    scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];

    //scrool view must be under main view - swap it
    UIView* natView = self.view;
    [self setView:scrollView];
    [self.view addSubview:natView];

    CGSize scrollViewContentSize = self.view.frame.size;
    [scrollView setContentSize:scrollViewContentSize];

    [self registerForKeyboardNotifications];
}

- (void)viewDidUnload {
    activeField = nil;
    scrollView = nil;
    [self unregisterForKeyboardNotifications];
    [super viewDidUnload];
}

- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShown:)
                                                 name:UIKeyboardWillShowNotification object:nil];

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

}

-(void)unregisterForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillShowNotification
                                                  object:nil];
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillHideNotification
                                                  object:nil];
}

- (void)keyboardWillShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGRect frame = self.view.frame;
    frame.size.height -= kbSize.height;
    CGPoint fOrigin = activeField.frame.origin;
    fOrigin.y -= scrollView.contentOffset.y;
    fOrigin.y += activeField.frame.size.height;
    if (!CGRectContainsPoint(frame, fOrigin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y + activeField.frame.size.height - frame.size.height);
        [scrollView setContentOffset:scrollPoint animated:YES];
    }
}

- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
     [scrollView setContentOffset:CGPointZero animated:YES];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    activeField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    activeField = nil;
}

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

PS: Spero che il codice aiuti qualcuno a rendere rapidamente l'effetto desiderato. (Xcode 4.5)




@ user271753

Per tornare alla visualizzazione originale aggiungi:

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



Come per i documenti , a partire da iOS 3.0, la UITableViewControllerclasse ridimensiona automaticamente e riposiziona la sua vista tabella quando è in corso la modifica dei campi di testo. Penso che non sia sufficiente inserire il campo di testo all'interno di un UITableViewCellcome alcuni hanno indicato.

Dai documenti :

Un controller di visualizzazione tabella supporta la modifica in linea delle righe di visualizzazione tabella; se, ad esempio, le righe hanno campi di testo incorporati in modalità di modifica, scorre la riga in corso di modifica sopra la tastiera virtuale che viene visualizzata.




Qui ho trovato la soluzione più semplice per gestire la tastiera.

Devi solo copiare e incollare sotto il codice di esempio e modificare il tuo campo di testo o qualsiasi vista che vuoi spostare.

Passo 1

Basta copiare e incollare sotto due metodi nel tuo controller

- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];
}

- (void)deregisterFromKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

Passo 2

registra e cancella le Notifiche della tastiera in viewWillAppear e viewWillDiseparano i metodi rispettivamente.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self registerForKeyboardNotifications];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self deregisterFromKeyboardNotifications];
    [super viewWillDisappear:animated];
}

Step-3

Ecco la parte dell'anima, basta sostituire il campo di testo e modificare l'altezza di quanto vuoi spostare al rialzo.

- (void)keyboardWasShown:(NSNotification *)notification
{
    NSDictionary* info = [notification userInfo];
    CGSize currentKeyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    //you need replace your textfield instance here
    CGPoint textFieldOrigin = self.tokenForPlaceField.frame.origin;
    CGFloat textFieldHeight = self.tokenForPlaceField.frame.size.height;

    CGRect visibleRect = self.view.frame;
    visibleRect.size.height -= currentKeyboardSize.height;

    if (!CGRectContainsPoint(visibleRect, textFieldOrigin))
    {
        //you can add yor desired height how much you want move keypad up, by replacing "textFieldHeight" below

        CGPoint scrollPoint = CGPointMake(0.0, textFieldOrigin.y - visibleRect.size.height  + textFieldHeight); //replace textFieldHeight to currentKeyboardSize.height, if you want to move up with more height
        [self.scrollView setContentOffset:scrollPoint animated:YES];
    }
}

- (void)keyboardWillBeHidden:(NSNotification *)notification
{
    [self.scrollView setContentOffset:CGPointZero animated:YES];
}

Riferimento : bene, per favore apprezzare questo ragazzo , che ha condiviso questo bel codice snip, soluzione pulita.

Spero che questo possa essere utile a qualcuno là fuori.




State cercando un buon tutorial per i principianti sull'argomento, ho trovato il miglior tutorial here .

Nel MIScrollView.hesempio, al fondo del tutorial assicurarsi di inserire uno spazio a

@property (nonatomic, retain) id backgroundTapDelegate;

come vedi.




Quando UITextFieldè in uno UITableViewCellscorrimento dovrebbe essere impostato automaticamente.

Se non lo è probabilmente è a causa di codice errato / setup di tableview.

Ad esempio quando ho ricaricato il mio lungo tavolo con uno UITextFieldin basso come segue,

-(void) viewWillAppear:(BOOL)animated
{
   [self.tableview reloadData];
}

poi il mio campo di testo in fondo era oscurato dalla tastiera che appariva quando ho cliccato all'interno del campo di testo.

Per risolvere questo ho dovuto fare questo -

-(void) viewWillAppear:(BOOL)animated
{
    //add the following line to fix issue
    [super viewWillAppear:animated];
    [self.tableview reloadData];
}



Questa è la soluzione che usa Swift.

import UIKit

class ExampleViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var scrollView: UIScrollView!

    @IBOutlet var textField1: UITextField!
    @IBOutlet var textField2: UITextField!
    @IBOutlet var textField3: UITextField!
    @IBOutlet var textField4: UITextField!
    @IBOutlet var textField5: UITextField!

    var activeTextField: UITextField!

    // MARK: - View
    override func viewDidLoad() {
        super.viewDidLoad()
        self.textField1.delegate = self
        self.textField2.delegate = self
        self.textField3.delegate = self
        self.textField4.delegate = self
        self.textField5.delegate = self
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.registerForKeyboardNotifications()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        self.unregisterFromKeyboardNotifications()
    }

    // MARK: - Keyboard

    // Call this method somewhere in your view controller setup code.
    func registerForKeyboardNotifications() {
        let center:  NSNotificationCenter = NSNotificationCenter.defaultCenter()
        center.addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
        center.addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
    }

    func unregisterFromKeyboardNotifications () {
        let center:  NSNotificationCenter = NSNotificationCenter.defaultCenter()
        center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
        center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
    }

    // Called when the UIKeyboardDidShowNotification is sent.
    func keyboardWasShown (notification: NSNotification) {
        let info : NSDictionary = notification.userInfo!
        let kbSize = (info.objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue() as CGRect!).size

        let contentInsets: UIEdgeInsets = 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.
        var aRect = self.view.frame
        aRect.size.height -= kbSize.height;
        if (!CGRectContainsPoint(aRect, self.activeTextField.frame.origin) ) {
            self.scrollView.scrollRectToVisible(self.activeTextField.frame, animated: true)
        }
    }

    // Called when the UIKeyboardWillHideNotification is sent
    func keyboardWillBeHidden (notification: NSNotification) {
        let contentInsets = UIEdgeInsetsZero;
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;
    }

    // MARK: -  Text Field

    func textFieldDidBeginEditing(textField: UITextField) {
        self.activeTextField = textField
    }

    func textFieldDidEndEditing(textField: UITextField) {
        self.activeTextField = nil
    }

}



Related