it-swarm.com.de

iPhone-Tastatur deckt UITextField ab

Ich habe eine App, bei der ich im Interface Builder eine UIView aufbaue, die ein Textfeld am unteren Rand der Ansicht hat. Wenn ich die App starte und versuche, Text in dieses Feld einzugeben, wird die Tastatur über das Feld hochgeschoben, sodass ich nicht sehen kann, was ich tippe, bis ich die Tastatur wieder verstecke. 

Hat jemand anderes dieses Problem gefunden und einen guten Weg gefunden, um dieses Problem zu lösen, ohne die übergeordnete Ansicht scrollbar zu machen oder das Textfeld auf dem Bildschirm nach oben zu verschieben?

119
Cruinh

Die übliche Lösung besteht darin, das Feld (und alles darüber) mit einer Animation nach oben zu verschieben und dann wieder nach unten zu verschieben. Möglicherweise müssen Sie das Textfeld und einige der anderen Elemente in eine andere Ansicht einfügen und die Ansicht als Einheit verschieben. (Ich nenne diese Dinge "Platten" wie in "tektonischen Platten", aber das ist nur ich). Aber hier ist die allgemeine Idee, wenn Sie nicht schick sein müssen.

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

Das hat Wunder gewirkt Schiebe-Uitextfelder

Insbesondere hat es den Vorteil, dass der Abstand der Folienanimation abhängig von der Position des Textfelds berechnet wird.

38
cidered

IQKeyboardManager Tun Sie dies für Sie mit NO LINE OF CODE. Sie müssen nur die zugehörige Quelldatei per Drag & Drop in das Projekt ziehen. IQKeyboardManager unterstützt auch Geräteorientierung, Automatische UIToolbar-Verwaltung, keyboardDistanceFromTextField und vieles mehr, als Sie denken.

enter image description here

Hier ist das Steuerungsflussdiagramm: Control Flow Chart

Schritt1: - Globale Benachrichtigungen von UITextField, UITextView und UIKeyboard in einer Singleton-Klasse hinzugefügt. Ich habe es IQKeyboardManager genannt.

Schritt2: - Wenn Sie UIKeyboardWillShowNotification-, UITextFieldTextDidBeginEditingNotification- oder UITextViewTextDidBeginEditingNotification-Benachrichtigungen gefunden haben, versuchen Sie, die topMostViewController-Instanz aus der UIWindow.rootViewController-Hierarchie abzurufen. Damit UITextFieldUITextView richtig aufgedeckt werden kann, muss der Frame von topMostViewController.view angepasst werden.

_/Step3: - Berechnete erwartete Bewegungsentfernung von topMostViewController.view in Bezug auf die erste Antwort UITextFieldUITextView.

_/Schritt4: - Verschiebt topMostViewController.view.frame entsprechend der erwarteten Bewegungsentfernung nach oben/unten.

Schritt5: - Wenn eine Benachrichtigung über UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification oder UITextViewTextDidEndEditingNotification gefunden wird, versuchen Sie erneut, die topMostViewController-Instanz aus der UIWindow.rootViewController-Hierarchie abzurufen.

Schritt6: - Berechnete gestörte Entfernung von topMostViewController.view, die an ihrer ursprünglichen Position wiederhergestellt werden muss.

Step7: - Wiederhergestellt topMostViewController.view.frame entsprechend der gestörten Entfernung.

Schritt8: - Instanziiertes Singleton IQKeyboardManager Klasseninstanz beim Laden der App, sodass sich UITextField/UITextView in der App automatisch an die erwartete Bewegungsentfernung anpassen.

Das ist alles

28

Um die Antwort von Amagrammer zu erweitern, finden Sie hier eine Beispielklasse:

LoginViewController.h

@interface LoginViewController : UIViewController <UITextFieldDelegate> {

}

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

Beachten Sie, dass wir das "UITextFieldDelegate" implementieren.

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

Wie wäre es mit der offiziellen Lösung: Bewegen von Inhalten, die sich unter der Tastatur befinden

Um Ihren Inhalt anzupassen, müssen Sie normalerweise die Größe eines oder .__ ändern. Weitere Ansichten und Positionieren, so dass das Textobjekt bleibt sichtbar. Die einfachste Möglichkeit, Textobjekte mit der Tastatur zu verwalten, ist um sie in ein UIScrollView-Objekt (oder eine seiner Unterklassen wie UITableView) einzubetten. Wenn die Tastatur angezeigt wird, müssen Sie alles tun setzt den Inhaltsbereich der Bildlaufansicht zurück und blättert das gewünschte Bild Textobjekt in Position. Also als Antwort auf eine UIKeyboardDidShowNotification, würde Ihre Handler-Methode die folgende:

  1. Holen Sie sich die Größe der Tastatur.
  2. Passen Sie den unteren Inhalt der Bildlaufansicht über die Tastatur an Höhe.
  3. Scrollen Sie das Zieltextfeld in die Ansicht.
// 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;
}
7
Mars

Ich habe das gleiche Problem in UITableView textField-Zellen. Ich löse dieses Problem durch Implementieren der folgenden Methode zum Abhören der Tastaturbenachrichtigung.

Beobachter für die Benachrichtigungen hier:

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

Behandeln Sie diese Benachrichtigung mithilfe der folgenden Funktion:

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

Sehen Sie sich das an ... __ Keine Mühe für Sie.

Diese Lösung ist sehr ordentlich. Alles, was Sie tun müssen, ist, Ihre Textfelder in ein UIScrollView hinzuzufügen und die Klasse in TPKeyboardAvoidingScollView zu ändern, wenn Sie Storyboards verwenden. Die Bildlaufansicht wird so erweitert, dass sie erkennt, wenn die Tastatur sichtbar ist, und sich in einem angemessenen Abstand über der Tastatur bewegt. Es ist die perfekte Lösung, weil es unabhängig von Ihrem _ UIViewController ist. In der oben genannten Klasse wird alles Notwendige erledigt. Danke an Michael Tyson und allen.

TPKeyboardAvoiding

5
ArunaNZ

Nachfolgend finden Sie eine schnelle Version von Amagrammers Antwort. Auch eine Variante mit dem UIKeyboardWillShowNotification -Ereignis, da ich die Größe der Tastaturen kennen musste, bevor die Ansicht verschoben wurde.

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)
}
5
Justin Domnitz

Es gab eine großartige Lösung in Bearbeitung von Textfeldern, ohne zu verdecken (Link jetzt tot, hier ist ein Wayback-Link: https://web.archive.org/web/20091123074029/http://acts-as-geek. blogspot.com/2009/11/editing-textfields-without-obscuring.html ). Es zeigt, wie Sie eine vorhandene UIView auf eine UIScrollView verschieben und automatisch scrollen, wenn die Tastatur angezeigt wird.

Ich habe es ein wenig überarbeitet, um die korrekte Höhe für die UIScrollView zu berechnen, wenn Steuerelemente (z. B. eine UITabBar) unter der UIScrollBar vorhanden sind. Siehe post Update uiview .

4
GargantuChet

Hier ist eine Lösung mit Xcode5, iOS7:

Verwenden Sie die Blöcke UITextfieldDelegate und Animation.

Dies ist fast der gesamte Code für den ViewController, aber ich wollte den Delegiertencode für diejenigen hinzufügen, die mit dem Delegatenmuster (wie ich) noch etwas nicht vertraut sind. Ich habe auch Code zum Ausblenden der Tastatur hinzugefügt, wenn Sie von der Textansicht weg tippen.

Sie können die Ansichten (Schaltflächen, Textfelder usw.) so hoch verschieben, wie Sie möchten. Stellen Sie sicher, dass Sie sie wieder einsetzen (+100 und später -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];
}
2
Ethan Parker

Ich denke, eine Möglichkeit wäre, Ihre gesamte Ansichtsposition von (x, y) nach (x, y-keybaardHeight) zu verschieben, wenn das Textfeld angeklickt wird, und es zurückzusetzen, wenn die Tastatur nicht angezeigt wird. Dies könnte ein wenig merkwürdig erscheinen kommt auf (vielleicht wäre es nicht schlimm, wenn Sie es animieren). 

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

Wenn Sie cocos2d im Hochformatmodus verwenden, ändern Sie zusätzlich zu Amagrammers Lösung diese Zeile:

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

zu diesem:

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

Wenn Sie cocos2d im Querformat verwenden, nehmen Sie die obige Änderung vor und ändern Sie die up-Werte in textFieldDidBeginEditing: und textFieldDidEndEditing:

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

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

https://github.com/ZulwiyozaPutra/Shift-Keyboard-Example Ich hoffe, diese Lösung hat geholfen. Sie sind alle Swift 3 geschrieben.

//
//  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)
    }
    
}

0
Zulwiyoza Putra

Drag & Drop-Framework, das ich in meinen Projekten verwende. Unterstützt die automatische Entlassung, wenn Sie außerhalb des Ersthelfer tippen oder blättern.

GTKeyboardHelper

0
mackross

Schieben Sie die Ansicht nach Bedarf auf und ab: 

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

Vergessen Sie nicht, self als UITextFieldDelegate und als aktuelles textField delegate zu setzen.

(Dank an Ammagrammer, dies ist nur eine kürzere Antwort mit Blöcken für Animationen.)

0
dulgan

Ich glaube, bei neueren Versionen von iOS (6.1+, möglicherweise sogar früher) wird die zugrunde liegende Ansicht, zumindest für UITableView, automatisch verkleinert, wenn die Tastatur erscheint. Sie müssen also nur das Textfeld in dieser Ansicht sichtbar machen. In init:

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

dann:

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

Ich hatte das gleiche Problem und fand, dass GTKeyboardHelper ein einfacher Ausweg ist.

Fügen Sie nach dem Ziehen und Ablegen des Frameworks in Ihrem Projekt die Header-Datei ein. __ Laden Sie das Beispielprojekt herunter, öffnen Sie es, und ziehen Sie das Objekt "Keyboard Helper" aus dem Objektabschnitt in der Xib-Datei in den Objektabschnitt im Interface-Builder Ihres Projekts.

Ziehen Sie alle Ihre Ansichten und lassen Sie sie als "Kinder" des "Keyboard Helper" ablegen.

0
Andrei Nagy

Ich habe noch etwas, wenn du willst. Der Punkt hier ist, dass Sie die Mitte Ihrer UIView für das Textfeld festlegen möchten, das Sie bearbeiten. 

Zuvor müssen Sie Ihr INITIAL_CENTER als CGPoint von self.view.center und Ihr INITIAL_VIEW als CGRect speichern. von self.view.frame in einer const-Eigenschaft.

Sie können eine Methode wie folgt erstellen:

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

Dann müssen Sie auf Ihrem UITextFieldDelegatecenterOn: (CGRect) mit folgenden Methoden aufrufen:

textFieldDidBeginEditing: (UITextField *)} _ als Parameter den Rahmen des Textfelds, auf das Sie zentrieren möchten. 

Und Sie müssen es in Ihrem Event-Handler aufrufen, wo Sie Ihre Tastatur schließen, 

textFieldDidEndEditing: (UITextField *)} kann eine der Möglichkeiten sein, den INITIAL_VIEW als Parameter von centerOn: (CGRect) zu setzen.

0
Jissay

Bitte schau dir meinen Kommentar dazu an:

iPhone - Tastatur verbirgt TextField

0
Dinesh reddy K

Wie gehen Sie mit der Situation um, in der sich die Tastatur befindet und der Rahmen mit Animation verkleinert und gescrollt wurde, sodass das Textfeld nicht abgedeckt wird. Wenn ich ein anderes Textfeld auswähle (das erste Textfeld noch bearbeitet), kann ich die Animation nicht noch einmal abspielen blättern Sie ggf. ein wenig weiter? Das Problem ist die Wiedergabe der gesamten Animation, wenn dies nicht erforderlich ist. Vielen Dank

0
anders