Frage

Ich habe eine app, wo, in Interface Builder , habe ich ein UIView einrichten, die ein Textfeld in der Nähe der Unterseite der Aussicht. Wenn ich die app laufen und versuchen, Text in das Feld eingeben, gleitet die Tastatur overtop des Feldes, so kann ich nicht sehen, was ich eingeben, bis ich die Tastatur wieder auszublenden.

Hat jemand sonst läuft in dieses Problem und fand eine gute Möglichkeit, es zu lösen, ohne entweder die übergeordnete Ansicht scrollbaren machen oder das Textfeld bewegt weiter oben im Bildschirm?

War es hilfreich?

Lösung

Die übliche Lösung ist das Feld (und alles darüber) nach oben mit einer Animation zu gleiten, und dann wieder nach unten, wenn Sie fertig sind. Sie können das Textfeld und einige der anderen Elemente in einer anderen Ansicht setzen müssen, und die Ansicht als eine Einheit schieben. (Ich nenne diese Dinge „Platten“, wie in „tektonischen Platten“, aber das ist nur meine Meinung). Aber hier ist die allgemeine Idee, wenn Sie nicht Lust bekommen 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];
}

Andere Tipps

Das wirkte Wunder für mich Schiebe UITextFields

Insbesondere hat es den Vorteil, dass die Folienanimationen Abstand Berechnung auf der Position des Textfeldes abhängig.

IQKeyboardManager dies mit für Sie tun keine Zeile Code , müssen nur zu ziehen und damit verbundene Quelldatei zu projizieren fallen. IQKeyboardManager auch unterstützen Geräteorientierung , Automatische UIToolbar Management keyboardDistanceFromTextField und viel mehr, als Sie denken.

eingeben Bild Beschreibung hier

Hier ist das Kontrollfluss-Diagramm: Control Flow Chart

Schritt 1: - am globalen Meldungen von UITextField, UITextView und UIKeyboard in einer Singleton-Klasse. Ich nannte es IQKeyboardManager .

Schritt 2: - Wenn gefunden UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotification oder UITextViewTextDidBeginEditingNotification Benachrichtigungen, dann versucht topMostViewController Instanz aus der UIWindow.rootViewController Hierarchie zu erhalten. Um UITextField / UITextView darauf richtig aufzudecken, muss topMostViewController.view der Rahmen angepasst werden.

Schritt 3: -. erwartete Bewegungsdistanz von topMostViewController.view bezüglich berechnet zuerst reagiert UITextField / UITextView

Schritt 4: -. Verschoben topMostViewController.view.frame nach oben / unten entsprechend der erwarteten Bewegungsdistanz

Schritt 5: -. Wenn gefunden UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification oder UITextViewTextDidEndEditingNotification Benachrichtigung, dann versuchen Sie es erneut topMostViewController Instanz aus der UIWindow.rootViewController Hierarchie zu erhalten

Step6: -. Berechnete gestört Entfernung von topMostViewController.view den ihm gestellt werden muss, ist ursprüngliche Position

Schritt 7: -. Wiederhergestellte topMostViewController.view.frame unten nach dem gestörten Abstand

Step8: - instanziiert Singletons IQKeyboardManager Klasseninstanz auf app Last, so jeder UITextField / UITextView in der App passt sich automatisch entsprechend der erwarteten Bewegungsdistanz.

Das ist alles

auf Amagrammer Antwort zu erweitern, ist hier eine Beispielklasse:

LoginViewController.h

@interface LoginViewController : UIViewController <UITextFieldDelegate> {

}

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

Beachten wir die "UITextFieldDelegate" setzen

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

Wie über die offizielle Lösung: Verschieben von Inhalten, die unter der Tastatur befinden

  

Anpassen des Inhalts der Regel vorübergehend beinhaltet Ändern der Größe eines oder   mehr Ansichten und ihre Positionierung, so dass das Textobjekt bleibt   sichtbar. Die einfachste Möglichkeit, Text zu verwalten Objekte mit der Tastatur   sie innerhalb eines UIScrollView Objekt (oder einer ihrer Unterklassen einzubetten   wie UITableView). Wenn die Tastatur angezeigt wird, alle müssen Sie tun   den Inhaltsbereich des Spiralansicht zurückgesetzt und bewegen die gewünschte   Textobjekt in Position. Somit wird in Reaktion auf ein   UIKeyboardDidShowNotification, Ihre Handler-Methode tun würde, die   Folgendes ein:

     
      
  1. Ermittelt die Größe der Tastatur.
  2.   
  3. Stellen Sie den unteren Inhalt Einsatz Ihrer Ansicht blättert durch die Tastatur   Höhe.
  4.   
  5. Blättern Sie in das Zieltextfeld in Sicht.
  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;
}

Ich habe das gleiche Problem in UITableView Textfield-Zellen gegenüber. Ich löse dieses Problem durch folgende Verfahren implementiert, um die Tastatur Benachrichtigung zu hören.

Observer für die Meldungen hier:

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

Griff jene Meldung von unten Funktion:

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

Überprüfen Sie dieses heraus. Kein Aufwand für Sie.

Diese Lösung ist sehr ordentlich. Alles, was Sie tun müssen, ist Ihre Textfelder in einem UIScrollView und ändern ihre Klasse TPKeyboardAvoidingScollView hinzuzufügen, wenn Sie Storyboards verwenden. Die Scroll-Ansicht wird so erweitert, dass sie erkennen würde, wenn Tastatur sichtbar ist und sich in einem angemessenen Abstand über Tastatur bewegen. Es ist die perfekte Lösung, weil seine unabhängig von Ihrer UIViewController. Jede notwendige Sache ist innerhalb der oben erwähnten Klasse getan. Dank Michael Tyson et all.

TPKeyboardAvoiding

Im Folgenden finden Sie eine schnelle Version von Amagrammer Antwort. Auch eine Variation des UIKeyboardWillShowNotification Ereignis verwenden, da ich die Tastaturen Größe wissen musste, bevor die Ansicht aus dem Weg zu bewegen.

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

Es war ein großer Durchlauf unter Bearbeitung Textfelder ohne Verschleierung (Link 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 eine bestehende UIView auf eine UIScrollView zu bewegen, und es automatisch zu bewegen, wenn die Tastatur angezeigt wird.

ich es ein bisschen aktualisiert haben die richtige Höhe für die UIScrollView zu berechnen, wenn es Kontrollen (wie ein UITabBar) unter dem UIScrollBar. Siehe Beitrag Aktualisierung uiview .

Hier ist eine Lösung mit Xcode5, iOS7:

die UITextFieldDelegate und Animationsblocks verwenden.

Dies ist fast der gesamte Code für die Viewcontroller, aber ich wollte den Delegaten Code für diejenigen, die noch etwas ungewohnt mit dem Delegierten Muster (wie ich) aufzunehmen. Ich enthalten Code auch die Tastatur auszublenden, wenn Sie aus dem Textview tippen entfernt.

Sie können die Ansichten bewegen (Schaltflächen, Textfelder, etc.) so hoch wie Sie gerade möchten sicherstellen, dass sie wieder an ihren Platz setzen (+100 dann 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];
}

Ich denke, eine Möglichkeit wäre, die ganzen Ansichten Position von (x, y) (x, y-keybaardHeight) zu bewegen, wenn das Textfeld geklickt wird und steckt es wieder, wenn die Tastatur des Feld verwiesen, vielleicht ein wenig seltsam aussehen wie der Blick kommt nur auf (vielleicht würde es nicht schlecht, wenn man es zu animieren).

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

Neben Amagrammer-Lösung, wenn Sie mit cocos2d im Portrait-Modus diese Zeile ändern:

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

folgt aus:

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

Wenn Sie cocos2d im Querformat verwenden, die oben Änderung vornehmen und schalten 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];
}

Ich hatte das gleiche Problem und fand GTKeyboardHelper ein einfacher Ausweg sein.

Nach dem Drag & Drop den Rahmen in Ihrem Projekt enthält die Header-Datei. Herunterladen und das Beispielprojekt öffnen, ziehen Sie dann den „Keyboard Helper“ Objekt aus dem Abschnitt Objekte im xib den Abschnitt Objekte in Ihrem Projekt Interface Builder.

Drag & Drop alle Ihre Ansichten Kinder des "Keyboard Helper" zu sein.

Drag-and-Drop-Framework, das ich in meinen Projekten verwenden. Unterstützt automatische Entlassung, wenn Sie außerhalb eines First Responder tippen oder wenn Sie blättern.

GTKeyboardHelper

Schieben Sie einfach den Blick nach oben und unten je nach Bedarf:

- (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 die eigentliche Textfield delegate zu setzen.

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

Ich habe etwas anderes, wenn Sie wollen. Der Punkt hier ist, dass Sie das Zentrum Ihrer UIView auf das Textfeld festlegen möchten Sie bearbeiten.

Davor müssen Sie speichern Ihre INITIAL_CENTER , als ein CGPoint , von self.view.center und INITIAL_VIEW als < strong> CGRect aus 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 auf UITextFieldDelegate , müssen Sie rufen Sie centerOn: (CGRect) in folgenden Methoden:

textFieldDidBeginEditing: (UITextField *) mit, als Parameter, der Rahmen des Textfeldes Sie zentrieren möchten.

Und Sie haben es in Ihren Event-Handler nennen, wo Sie Ihre Tastatur zu schließen,

textFieldDidEndEditing: (UITextField *) kann eine der Möglichkeiten, es zu tun, die INITIAL_VIEW als Parameter von centerOn setzen. (CGRect)

Ich glaube, auf neueren Versionen von iOS (6.1+, möglicherweise sogar früher), die zugrunde liegende Ansicht, zumindest für UITableView, Auto-schrumpft, wenn die Tastatur erscheint. Sie müssen also nur auf 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];
}

https://github.com/ZulwiyozaPutra/Shift-Keyboard-Example ich hoffe, dass diese Lösung 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)
    }
    
}

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top