it-swarm.com.de

Wie kann ich ein UITextField nach oben bewegen, wenn die Tastatur vorhanden ist - beim Starten der Bearbeitung?

Mit dem iOS SDK:

Ich habe eine UIView mit UITextFields, die eine Tastatur aufruft. Ich brauche es, um:

  1. Lassen Sie den Inhalt der UIScrollView scrollen, um die anderen Textfelder anzuzeigen, sobald die Tastatur aufgerufen wird

  2. Automatisch "springen" (durch Aufwärtsblättern) oder Verkürzen

Ich weiß, dass ich eine UIScrollView brauche. Ich habe versucht, die Klasse meiner UIView in eine UIScrollView zu ändern, aber ich kann die Textfelder immer noch nicht nach oben oder unten scrollen. 

Benötige ich eine UIView und eine UIScrollView? Geht einer in den anderen?

Was muss implementiert werden, um automatisch zum aktiven Textfeld zu blättern?

Im Idealfall wird so viel der Einrichtung der Komponenten wie möglich im Interface Builder vorgenommen. Ich möchte nur Code schreiben, was es braucht.

Hinweis: Die UIView (oder UIScrollView), mit der ich arbeite, wird von einer Tab-Leiste (UITabBar) aufgerufen, die normal funktionieren muss.


Bearbeiten: Ich füge die Bildlaufleiste nur für die Tastatur hinzu. Auch wenn dies nicht erforderlich ist, bietet es mir eine bessere Benutzeroberfläche, da der Benutzer beispielsweise scrollen und Textfelder ändern kann. 

Ich habe es funktioniert, wo ich die Framegröße der UIScrollView ändere, wenn die Tastatur hoch und runter geht. Ich verwende einfach: 

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

Dies bewegt sich jedoch nicht automatisch "nach oben" oder zentriert die unteren Textfelder im sichtbaren Bereich, was ich wirklich gerne hätte.

1609
philfreo
  1. Sie benötigen ein ScrollView nur, wenn die Inhalte, die Sie jetzt haben, nicht in den iPhone-Bildschirm passen (Wenn Sie ScrollView als Übersicht der Komponenten hinzufügen. Nur um das TextField-Fenster aufzurufen, wenn die Tastatur hochgefahren wird, dann es wird nicht benötigt.)

  2. Um textfields anzuzeigen, ohne von der Tastatur ausgeblendet zu werden, wird standardmäßig die Ansicht mit Textfeldern nach oben/unten verschoben, wenn die Tastatur angezeigt wird.

Hier ist ein Beispielcode:

#define kOFFSET_FOR_KEYBOARD 80.0

-(void)keyboardWillShow {
    // Animate the current view out of the way
    if (self.view.frame.Origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.Origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}

-(void)keyboardWillHide {
    if (self.view.frame.Origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.Origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
    if ([sender isEqual:mailTf])
    {
        //move the main view, so that the keyboard does not hide it.
        if  (self.view.frame.Origin.y >= 0)
        {
            [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 -= kOFFSET_FOR_KEYBOARD;
        rect.size.height += kOFFSET_FOR_KEYBOARD;
    }
    else
    {
        // revert back to the normal state.
        rect.Origin.y += kOFFSET_FOR_KEYBOARD;
        rect.size.height -= kOFFSET_FOR_KEYBOARD;
    }
    self.view.frame = rect;

    [UIView commitAnimations];
}


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

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

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

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}
999
RPDP

Ich hatte auch eine Menge Probleme mit einem UIScrollView, das aus mehreren UITextFields bestand, von denen einer oder mehrere von ihnen beim Editieren durch die Tastatur verdeckt würden. 

Folgendes sollten Sie beachten, wenn Ihr UIScrollView nicht ordnungsgemäß gescrollt wird. 

1) Stellen Sie sicher, dass Ihre contentSize die Rahmengröße UIScrollView überschreitet. Um UIScrollViews zu verstehen, ist es so, dass UIScrollView wie ein Anzeigefenster für den in contentSize definierten Inhalt ist. Wenn also UIScrollview irgendwo scrollen darf, muss contentSize größer als UIScrollView sein. Andernfalls ist kein Bildlauf erforderlich, da alles, was in contentSize definiert ist, bereits sichtbar ist. BTW, Standardinhalt contentSize = CGSizeZero.

2) Nachdem Sie nun verstanden haben, dass UIScrollView wirklich ein Fenster in Ihren "Inhalt" ist, besteht der Weg, um sicherzustellen, dass die Tastatur Ihr UIScrollView's-Anzeige "Fenster" nicht verdeckt, darin, die Größe von UIScrollView zu ändern Wenn die Tastatur vorhanden ist, haben Sie das Fenster UIScrollView, das nur der ursprünglichen UIScrollView frame.size.höhe minus der Höhe der Tastatur entspricht. Dadurch wird sichergestellt, dass Ihr Fenster nur aus diesem kleinen sichtbaren Bereich besteht.

3) Hier ist der Haken: Als ich das zum ersten Mal implementierte, dachte ich, ich müsste CGRect des bearbeiteten Textfelds bekommen und die UIScrollView's scrollRecToVisible-Methode aufrufen. Ich habe die UITextFieldDelegate Methode textFieldDidBeginEditing mit dem Aufruf der scrollRecToVisible Methode implementiert. Dies funktionierte tatsächlich mit einem seltsamen Nebeneffekt, dass das Scrollen Einrasten der UITextField in Position wäre. Die längste Zeit konnte ich nicht herausfinden, was es war. Dann habe ich die textFieldDidBeginEditing Delegate-Methode auskommentiert und es funktioniert alles !! (???). Wie sich herausgestellt hat, bringt der UIScrollView tatsächlich den aktuell bearbeiteten UITextField implizit in das sichtbare Fenster. Meine Implementierung der Methode UITextFieldDelegate und der darauffolgende Aufruf von scrollRecToVisible waren überflüssig und verursachten die seltsame Nebenwirkung.

Hier sind die Schritte, um Ihr UITextField in einem UIScrollView richtig in die richtige Position zu rollen, wenn die Tastatur angezeigt wird.

// 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. Registrieren Sie sich für die Tastaturbenachrichtigungen unter viewDidLoad
  2. Heben Sie die Registrierung für die Tastaturnachrichten bei viewDidUnload auf.
  3. Stellen Sie sicher, dass contentSize eingestellt ist und größer als Ihr UIScrollView bei viewDidLoad ist.
  4. Verkleinern die UIScrollView, wenn die Tastatur vorhanden ist
  5. Zurückkehren die UIScrollView, wenn die Tastatur wegfällt.
  6. Verwenden Sie ein Ivar, um festzustellen, ob die Tastatur bereits auf dem Bildschirm angezeigt wird, da die Tastaturbenachrichtigungen jedes Mal gesendet werden, wenn ein UITextField-Tabulator aktiviert wird, auch wenn die Tastatur bereits vorhanden ist, um Verkleinern der UIScrollView wenn es schon geschrumpft ist

Zu beachten ist, dass UIKeyboardWillShowNotification auch dann ausgelöst wird, wenn die Tastatur bereits auf dem Bildschirm angezeigt wird, wenn Sie auf ein anderes UITextField tippen. Ich habe mich darum gekümmert, indem ich ein ivar verwendet habe, um zu verhindern, dass UIScrollView geändert wird, wenn die Tastatur bereits auf dem Bildschirm angezeigt wird. Das unbeabsichtigte Ändern der Größe von UIScrollView, wenn sich die Tastatur bereits dort befindet, wäre verheerend!

Ich hoffe, dieser Code erspart einigen von Ihnen Kopfschmerzen. 

439
Shiun

Es ist eigentlich am besten, nur die Implementierung von Apple zu verwenden, wie in den docs beschrieben. Der von ihnen bereitgestellte Code ist jedoch fehlerhaft. Ersetzen Sie den in keyboardWasShown: direkt unter den Kommentaren gefundenen Abschnitt durch Folgendes:

NSDictionary* info = [aNotification userInfo];
CGRect keyPadFrame=[[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.view];
CGSize kbSize =keyPadFrame.size;
CGRect activeRect=[self.view convertRect:activeField.frame fromView:activeField.superview];
CGRect aRect = self.view.bounds;
aRect.size.height -= (kbSize.height);

CGPoint Origin =  activeRect.Origin;
Origin.y -= backScrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, Origin)) {
    CGPoint scrollPoint = CGPointMake(0.0,CGRectGetMaxY(activeRect)-(aRect.size.height));
    [backScrollView setContentOffset:scrollPoint animated:YES];
}

Die Probleme mit Apples Code lauten wie folgt: (1) Sie berechnen immer, ob sich der Punkt innerhalb des Rahmens der Ansicht befindet, es handelt sich jedoch um eine ScrollView, sodass der Bildlauf möglicherweise bereits gescrollt wurde und Sie diesen Versatz berücksichtigen müssen:

Origin.y -= scrollView.contentOffset.y

(2) Sie verschieben das contentOffset um die Höhe der Tastatur, aber wir möchten das Gegenteil (wir möchten die contentOffset um die auf dem Bildschirm sichtbare Höhe verschieben, nicht die, was nicht ist):

activeField.frame.Origin.y-(aRect.size.height)
265
DK_

Rufen Sie in textFieldDidBeginEditting und in textFieldDidEndEditing die Funktion [self animateTextField:textField up:YES] so auf: 

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

Ich hoffe, dieser Code wird Ihnen helfen. 

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

Nur TextFields verwenden:

1a) Verwenden von Interface Builder: Wählen Sie Alle TextFields => Bearbeiten => Einbetten in => ScrollView

1b) Manuelles Einbetten von TextFields in UIScrollView mit dem Namen scrollView

2) Setze UITextFieldDelegate

3) Setzen Sie jeden textField.delegate = self; (oder stellen Sie Verbindungen in Interface Builder her)

4) Kopieren/Einfügen:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGPoint scrollPoint = CGPointMake(0, textField.frame.Origin.y);
    [scrollView setContentOffset:scrollPoint animated:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [scrollView setContentOffset:CGPointZero animated:YES];
}
133
DAS

Für Universal Solution war mein Ansatz für die Implementierung von IQKeyboardManager .

enter image description here

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

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

_/Schritt3: - Ich habe die erwartete Bewegungsentfernung von topMostViewController.view in Bezug auf die zuerst angesprochene UITextFieldUITextView berechnet.

_/Schritt4: - Ich habe den topMostViewController.view.frame entsprechend der erwarteten Bewegungsentfernung nach oben/unten verschoben.

Schritt5: - Wenn ich UIKeyboardWillHideNotification-, UITextFieldTextDidEndEditingNotification- oder UITextViewTextDidEndEditingNotification-Benachrichtigung gefunden habe, versuche ich erneut, die topMostViewController-Instanz aus der UIWindow.rootViewController-Hierarchie abzurufen.

Schritt6: - Ich habe den gestörten Abstand von topMostViewController.view berechnet, der an seiner ursprünglichen Position wiederhergestellt werden muss.

Step7: - Ich habe topMostViewController.view.frame entsprechend der gestörten Entfernung restauriert.

Step8: - Ich instanziierte das Singleton IQKeyboardManager -Klasseninstanz beim Laden der App, so dass sich jeder UITextFieldUITextView in der App automatisch an die erwartete Bewegungsentfernung anpassen.

Das ist alles IQKeyboardManager erledigt für Sie mit _/NO LINE OF CODE wirklich !! Sie müssen nur die zugehörige Quelldatei per Drag & Drop in das Projekt einfügen. IQKeyboardManager unterstützt auch Geräteorientierung, Automatic UIToolbar Management, KeybkeyboardDistanceFromTextField und vieles mehr, als Sie denken.

110

Ich habe eine universelle Drop-In-Klasse UIScrollView, UITableView und sogar UICollectionView zusammengestellt, die dafür sorgt, dass alle Textfelder innerhalb der Tastatur aus der Tastatur verschoben werden.

Wenn die Tastatur erscheint, sucht die Unterklasse die zu bearbeitende Unteransicht und passt ihren Frame- und Inhalt-Versatz an, um sicherzustellen, dass die Ansicht sichtbar ist, wobei die Animation dem Popup der Tastatur entspricht. Wenn die Tastatur ausgeblendet wird, wird die vorherige Größe wiederhergestellt.

Es sollte grundsätzlich mit jedem Setup funktionieren, entweder mit einer UITableView-basierten Schnittstelle oder mit Ansichten, die manuell platziert wurden.

Hier ist tis: Lösung zum Verschieben von Textfeldern aus der Tastatur

101
Michael Tyson

Für SwiftProgrammierer:

Dies erledigt alles für Sie, fügen Sie diese einfach in Ihre View-Controller-Klasse ein, implementieren Sie die UITextFieldDelegate in Ihren View-Controller und setzen Sie den Delegaten von textField auf self

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

Implementieren Sie die Delegate-Callback-Methoden:

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()
}
85
Satnam Sync

Es gibt bereits viele Antworten, aber dennoch hatte keine der oben genannten Lösungen alles, was man für eine "perfekte" fehlerfreie, abwärtskompatible und flimmerfreie Animation benötigt. (Fehler beim Animieren von Frames/Begrenzungen und contentOffset zusammen, unterschiedliche Oberflächenausrichtungen, iPad-Split-Tastatur, ...)
Lassen Sie mich meine Lösung teilen: 
(vorausgesetzt, Sie haben UIKeyboardWill(Show|Hide)Notification eingerichtet)

// Called when UIKeyboardWillShowNotification is sent
- (void)keyboardWillShow:(NSNotification*)notification
{
    // if we have no view or are not visible in any window, we don't care
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }

    NSDictionary *userInfo = [notification userInfo];

    CGRect keyboardFrameInWindow;
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindow];

    // the keyboard frame is specified in window-level coordinates. this calculates the frame as if it were a subview of our view, making it a sibling of the scroll view
    CGRect keyboardFrameInView = [self.view convertRect:keyboardFrameInWindow fromView:nil];

    CGRect scrollViewKeyboardIntersection = CGRectIntersection(_scrollView.frame, keyboardFrameInView);
    UIEdgeInsets newContentInsets = UIEdgeInsetsMake(0, 0, scrollViewKeyboardIntersection.size.height, 0);

    // this is an old animation method, but the only one that retains compaitiblity between parameters (duration, curve) and the values contained in the userInfo-Dictionary.
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];

    _scrollView.contentInset = newContentInsets;
    _scrollView.scrollIndicatorInsets = newContentInsets;

    /*
     * Depending on visual layout, _focusedControl should either be the input field (UITextField,..) or another element
     * that should be visible, e.g. a purchase button below an amount text field
     * it makes sense to set _focusedControl in delegates like -textFieldShouldBeginEditing: if you have multiple input fields
     */
    if (_focusedControl) {
        CGRect controlFrameInScrollView = [_scrollView convertRect:_focusedControl.bounds fromView:_focusedControl]; // if the control is a deep in the hierarchy below the scroll view, this will calculate the frame as if it were a direct subview
        controlFrameInScrollView = CGRectInset(controlFrameInScrollView, 0, -10); // replace 10 with any Nice visual offset between control and keyboard or control and top of the scroll view.

        CGFloat controlVisualOffsetToTopOfScrollview = controlFrameInScrollView.Origin.y - _scrollView.contentOffset.y;
        CGFloat controlVisualBottom = controlVisualOffsetToTopOfScrollview + controlFrameInScrollView.size.height;

        // this is the visible part of the scroll view that is not hidden by the keyboard
        CGFloat scrollViewVisibleHeight = _scrollView.frame.size.height - scrollViewKeyboardIntersection.size.height;

        if (controlVisualBottom > scrollViewVisibleHeight) { // check if the keyboard will hide the control in question
            // scroll up until the control is in place
            CGPoint newContentOffset = _scrollView.contentOffset;
            newContentOffset.y += (controlVisualBottom - scrollViewVisibleHeight);

            // make sure we don't set an impossible offset caused by the "Nice visual offset"
            // if a control is at the bottom of the scroll view, it will end up just above the keyboard to eliminate scrolling inconsistencies
            newContentOffset.y = MIN(newContentOffset.y, _scrollView.contentSize.height - scrollViewVisibleHeight);

            [_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
        } else if (controlFrameInScrollView.Origin.y < _scrollView.contentOffset.y) {
            // if the control is not fully visible, make it so (useful if the user taps on a partially visible input field
            CGPoint newContentOffset = _scrollView.contentOffset;
            newContentOffset.y = controlFrameInScrollView.Origin.y;

            [_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
        }
    }

    [UIView commitAnimations];
}


// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillHide:(NSNotification*)notification
{
    // if we have no view or are not visible in any window, we don't care
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }

    NSDictionary *userInfo = notification.userInfo;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];

    // undo all that keyboardWillShow-magic
    // the scroll view will adjust its contentOffset apropriately
    _scrollView.contentInset = UIEdgeInsetsZero;
    _scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;

    [UIView commitAnimations];
}
63
Martin Ullrich

Shiun sagte: "Wie sich herausstellte, bringt das UIScrollView tatsächlich das aktuell bearbeitete UITextField implizit in das sichtbare Fenster." Dies scheint für iOS 3.1.3 der Fall zu sein, nicht jedoch für 3.2, 4.0 oder 4.1. Ich musste ein explizites scrollRectToVisible hinzufügen, um das UITextField auf iOS> = 3.2 sichtbar zu machen.

61
cbranch

Eine Sache, die Sie berücksichtigen sollten, ist, ob Sie eine UITextField alleine verwenden möchten. Ich habe keine gut konzipierten iPhone-Apps gefunden, die UITextFields außerhalb von UITableViewCells verwenden.

Es ist etwas mehr Arbeit, aber ich empfehle Ihnen, alle Dateneingabesichten und Tabellensichten zu implementieren. Fügen Sie Ihrer UITextView eine UITableViewCells hinzu.

46

Dieses Dokument enthält eine Lösung für dieses Problem. Sehen Sie sich den Quellcode unter "Verschieben von Inhalten unter der Tastatur" an. Das ist ziemlich einfach.

BEARBEITEN: Es wurde eine kleine Störung im Beispiel bemerkt. Wahrscheinlich möchten Sie auf UIKeyboardWillHideNotification statt auf UIKeyboardDidHideNotification achten. Andernfalls wird die Bildlaufansicht hinter der Tastatur für die Dauer der Animation zum Schließen der Tastatur abgeschnitten.

45
Mihai Damian

Einfachste Lösung gefunden  

- (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];
}
32
Xar E Ahmer

Kleine Korrektur, die für viele UITextFields funktioniert

#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]; 
}
31
tt.Kilew

Der RPDP-Code verschiebt das Textfeld erfolgreich von der Tastatur. Wenn Sie jedoch nach dem Scrollen nach oben und nach oben blättern, wurde der obere Bereich aus der Ansicht verschoben. Dies gilt für den Simulator und das Gerät. Um den Inhalt oben in dieser Ansicht zu lesen, muss die Ansicht neu geladen werden.

Soll der folgende Code nicht die Sicht nach unten bringen?

else
{
    // revert back to the normal state.
    rect.Origin.y += kOFFSET_FOR_KEYBOARD;
    rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
29
Steve

Ich bin nicht sicher, ob die Ansicht nach oben zu verschieben, der richtige Ansatz ist. Ich habe es auf eine andere Weise gemacht, indem ich die Größe der UIScrollView geändert habe. Ich habe es auf einem kleinen Artikel ausführlich erklärt.

23
Jose Muanis

Um zum ursprünglichen Ansichtszustand zurückzukehren, fügen Sie Folgendes hinzu:

-(void)textFieldDidEndEditing:(UITextField *)sender

{
    //move the main view, so that the keyboard does not hide it.
    if  (self.view.frame.Origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}
21

Es gibt so viele Lösungen, aber ich habe einige Stunden damit verbracht, bis es funktioniert. Also habe ich diesen Code hier eingefügt (einfach in das Projekt einfügen, Änderungen müssen nicht vorgenommen werden):

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

P .: Ich hoffe, der Code hilft jemandem, schnell den gewünschten Effekt zu erzielen. (Xcode 4.5)

19
HotJard

@ user271753

Um Ihre Ansicht wieder auf das Original zu bringen, fügen Sie Folgendes hinzu:

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

Versuchen Sie diesen kurzen Trick.

- (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 = textField.frame.Origin.y / 2; // 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];
}
18
Sourabh Sharma

Es ist keine Bildlaufansicht erforderlich, um den Ansichtsrahmen verschieben zu können. Sie können den Rahmen einer viewcontroller's-Ansicht ändern, sodass die gesamte Ansicht gerade so weit nach oben verschoben wird, dass das erste Antwortfeld über der Tastatur angezeigt wird. Als ich auf dieses Problem stieß, habe ich eine Unterklasse von UIViewController erstellt, die dies tut. Es wird darauf hingewiesen, dass auf der Tastatur eine Benachrichtigung angezeigt wird, und die Unteransicht des ersten Antworters wird angezeigt (und, falls erforderlich), wird die Hauptansicht gerade nach oben bewegt, sodass sich der erste Antwortende über der Tastatur befindet. Wenn die Tastatur ausgeblendet wird, wird die Ansicht dahin animiert, wo sie sich befand.

Um diese Unterklasse zu verwenden, machen Sie aus Ihrem benutzerdefinierten View-Controller eine Unterklasse von GMKeyboardVC und erbt diese Funktion (stellen Sie sicher, dass Sie viewWillAppear und viewWillDisappear implementieren, die sie super aufrufen müssen). Die Klasse ist auf github .

16
progrmr

Gemäß the docs (ab iOS 3.0) ändert die UITableViewController-Klasse automatisch ihre Tabellensicht, wenn Textfelder inline bearbeitet werden. Ich denke, es reicht nicht aus, das Textfeld in eine UITableViewCell zu setzen, wie einige angegeben haben.

Von den Dokumenten :

Ein Table-View-Controller unterstützt die Inline-Bearbeitung von Table-View-Zeilen; Wenn z. B. Zeilen im Bearbeitungsmodus eingebettete Textfelder enthalten, wird es scrollt die Zeile, die gerade bearbeitet wird, über der virtuellen Tastatur, die .__ ist. angezeigt.

12
Dheeraj V.S.

Hier ist die Hack-Lösung, die ich für ein bestimmtes Layout gefunden habe. Diese Lösung ähnelt der Matt-Gallagher-Lösung, indem ein Abschnitt in die Ansicht gerollt wird. Ich bin immer noch neu in der iPhone-Entwicklung und weiß nicht, wie die Layouts funktionieren. Also dieser Hack.

Meine Implementierung musste Scrollen unterstützen, wenn Sie in ein Feld klicken, und auch scrollen, wenn der Benutzer als Nächstes auf der Tastatur auswählt.

Ich hatte eine UIView mit einer Höhe von 775. Die Bedienelemente sind im Wesentlichen in 3er-Gruppen über einen großen Raum verteilt. Ich habe das folgende IB-Layout erhalten.

UIView -> UIScrollView -> [UI Components]

Hier kommt der Hack

Ich habe die UIScrollView-Höhe auf 500 Einheiten größer als das tatsächliche Layout (1250) eingestellt. Ich habe dann ein Array mit den absoluten Positionen erstellt, zu denen ich scrollen muss, und einer einfachen Funktion, um sie basierend auf der IB-Tag-Nummer zu erhalten.

static NSInteger stepRange[] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140, 140, 140, 140, 410
};

NSInteger getScrollPos(NSInteger i) {
    if (i < TXT_FIELD_INDEX_MIN || i > TXT_FIELD_INDEX_MAX) {
        return 0 ;
    return stepRange[i] ;
}

Jetzt müssen Sie nur noch die folgenden beiden Codezeilen in textFieldDidBeginEditing und textFieldShouldReturn verwenden (letzteres, wenn Sie eine nächste Feldnavigation erstellen).

CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
[self.scrollView setContentOffset:point animated:YES] ;

Ein Beispiel.

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
    [self.scrollView setContentOffset:point animated:YES] ;
}


- (BOOL)textFieldShouldReturn:(UITextField *)textField {

    NSInteger nextTag = textField.tag + 1;
    UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];

    if (nextResponder) {
        [nextResponder becomeFirstResponder];
        CGPoint point = CGPointMake(0, getScrollPos(nextTag)) ;
        [self.scrollView setContentOffset:point animated:YES] ;
    }
    else{
        [textField resignFirstResponder];
    }

    return YES ;
}

Diese Methode "rollt" nicht wie andere Methoden zurück. Dies war keine Voraussetzung. Dies war wieder eine ziemlich "große" UIView, und ich hatte keine Tage Zeit, um die internen Layout-Engines zu lernen.

12
Steve McFarlin

Hier Ich habe die einfachste Lösung für den Umgang mit der Tastatur gefunden.

Sie müssen lediglich Beispielcode kopieren und einfügen und Ihr Textfeld oder die Ansicht ändern, die Sie nach oben verschieben möchten.

Schritt 1 

Kopieren Sie einfach zwei Methoden in Ihren 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];
}

Schritt 2 

registrieren und Abmelden der Tastaturbenachrichtigungen in viewWillAppear und viewWillDisappear -Methoden.

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

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

Schritt 3 

Hier kommt der Soul-Teil. Ersetzen Sie einfach Ihr Textfeld und ändern Sie Höhe, wie viel Sie nach oben bewegen möchten.

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

Referenz: Na ja, Bitte schätzen Sie diesen Kerl , der diesen schönen Code-Snip geteilt hat, saubere Lösung.

Hoffe, das wäre sicherlich hilfreich für jemanden da draußen.

11
swiftBoy

Swift 4

Sie können problemlos UITextField oder UIView mit UIKeyBoard mit Animationauf und ab bewegen enter image description here

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var textField: UITextField!
    @IBOutlet var chatView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: .UIKeyboardWillChangeFrame, object: nil)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.resignFirstResponder()
    }

    @objc func keyboardWillChange(notification: NSNotification) {

        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
        let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let deltaY = targetFrame.Origin.y - curFrame.Origin.y
        print("deltaY",deltaY)

        UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
            self.chatView.frame.Origin.y+=deltaY // Here You Can Change UIView To UITextField
        },completion: nil)
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

}
11
ZAFAR007

Auf der Suche nach einem guten Tutorial für Anfänger zu diesem Thema, fand das beste Tutorial hier .

Stellen Sie im MIScrollView.h-Beispiel am Ende des Tutorials sicher, dass Sie ein Leerzeichen in setzen

@property (nonatomic, retain) id backgroundTapDelegate;

wie du siehst.

10
savagenoob

Wenn sich UITextField in einer UITableViewCell befindet, sollte das Scrollen automatisch eingerichtet werden.

Wenn dies nicht der Fall ist, liegt dies wahrscheinlich an einem falschen Code/Setup der Tabellenansicht.

Zum Beispiel, wenn ich meine lange Tabelle mit einer UITextField am unteren Ende wie folgt neu geladen habe, 

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

dann wurde mein Textfeld am unteren Rand von der Tastatur verdeckt, die angezeigt wurde, als ich in das Textfeld klickte.

Um das zu beheben, musste ich das tun -

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

Mit diesem Drittanbieter brauchen Sie nicht einmal eine Zeile zu schreiben

https://github.com/hackiftekhar/IQKeyboardManager

laden Sie das Projekt herunter und ziehen Sie den IQKeyboardManager per Drag & Drop in Ihr Projekt. Wenn Sie ein Problem finden, lesen Sie bitte README document.

Jungs wirklich seine Kopfschmerzen zu entfernen, um die Tastatur zu verwalten ..

Danke und viel Glück!

9
Arvind Kumar

Hinweis : Diese Antwort setzt voraus, dass sich Ihr textField in einem scrollView befindet.

Ich gehe lieber damit um, indem ich scrollContentInset und scrollContentOffset benutze, anstatt mit den Frames meiner Ansicht zu verwechseln.

Lassen Sie uns zunächst die Tastaturbenachrichtigungen abhören 

//call this from viewWillAppear
-(void)addKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}
//call this from viewWillDisappear
-(void)removeKeyboardNotifications{
    [[NSNotificationCenter default
    Center] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

Der nächste Schritt besteht darin, eine Eigenschaft beizubehalten, die den aktuellen ersten Responder darstellt (UITextfield/UITextVIew, der aktuell die Tastatur besitzt).

Wir setzen die Delegatmethoden, um diese Eigenschaft festzulegen. Wenn Sie eine andere Komponente verwenden, benötigen Sie etwas Ähnliches.

Beachten Sie, dass wir für textfield es in didBeginEditing und für textView in shouldBeginEditing setzen. Dies liegt daran, dass textViewDidBeginEditing aus irgendeinem Grund nach UIKeyboardWillShowNotification aufgerufen wird. 

-(BOOL)textViewShouldBeginEditing:(UITextView * )textView{
    self.currentFirstResponder = textView;
    return YES;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField{
    self.currentFirstResponder = textField;
}

Schließlich ist hier die Magie

- (void)keyboardWillShow:(NSNotification*)aNotification{
    NSDictionary* info = [aNotification userInfo];
    CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];


    /*if currentFirstResponder is overlayed by the keyboard, move it so it bottom ends where the keyboard begins*/
    if(self.currentFirstResponder){

        //keyboard Origin in currentFirstResponderFrame
        CGPoint keyboardOrigin = [self.currentFirstResponder convertPoint:kbFrame.Origin fromView:nil];

        float spaceBetweenFirstResponderAndKeyboard = abs(self.currentFirstResponder.frame.size.height-keyboardOrigin.y);

        //only scroll the scrollview if keyboard overlays the first responder
        if(spaceBetweenFirstResponderAndKeyboard>0){
            //if i call setContentOffset:animate:YES it behaves differently, not sure why
            [UIView animateWithDuration:0.25 animations:^{
                [self.scrollView setContentOffset:CGPointMake(0,self.scrollView.contentOffset.y+spaceBetweenFirstResponderAndKeyboard)];
            }];
        }
    }

    //set bottom inset to the keyboard height so you can still scroll the whole content

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbFrame.size.height, 0.0);
    _scrollView.contentInset = contentInsets;
    _scrollView.scrollIndicatorInsets = contentInsets;

}

- (void)keyboardWillHide:(NSNotification*)aNotification{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    _scrollView.contentInset = contentInsets;
    _scrollView.scrollIndicatorInsets = contentInsets;
}
8
Juraj Petrik

Dies ist die Lösung mit 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
    }

}
8
Homam

Sie müssen scrollview programmgesteuert mit einer bestimmten Bildgröße hinzufügen. Sie müssen UIScrollViewDelegate in der .h-Datei hinzufügen. Sie müssen die Scrollansicht aktivieren, die Sie in viewDidLoad () schreiben müssen.

scrollview.scrollEnabled=YES;
scrollview.delegate=self;

scrollview.frame = CGRectMake(x,y,width,height);
//---set the content size of the scroll view--- 

[scrollview setContentSize:CGSizeMake(height,width)];

Auf diese Weise können Sie die Werte für x, y, Breite und Höhe hinzufügen. Ich denke, das wird Ihnen helfen.

7
deepti

Versuche dies:

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
    if ([sender isEqual:self.m_Sp_Contact])
    {
        [self.m_Scroller setContentOffset:CGPointMake(0, 105)animated:YES];          
    }
}
7
user1105624

Swift 2.0:

Fügen Sie eine UIScrollView und TextFields oben hinzu. Machen Sie Storyboard-Referenzen zu VC.

@IBOutlet weak var username: UITextField!
@IBOutlet weak var password: UITextField!
@IBOutlet weak var scrollView: UIScrollView!

Fügen Sie diese Methoden hinzu: UITextFieldDelegate & UIScrollViewDelegate.

//MARK:- TEXTFIELD METHODS
    func textFieldShouldReturn(textField: UITextField) -> Bool {

        if(username.returnKeyType == UIReturnKeyType.Default) {
            password.becomeFirstResponder()
        }
        textField.resignFirstResponder()
        return true
    }
    func textFieldDidBeginEditing(textField: UITextField) {

        dispatch_async(dispatch_get_main_queue()) {

            let scrollPoint:CGPoint = CGPointMake(0,textField.frame.Origin.y/4)
            self.scrollView!.setContentOffset(scrollPoint, animated: true);
        }
    }
    func textFieldShouldEndEditing(textField: UITextField) -> Bool {

        dispatch_async(dispatch_get_main_queue()) {
          UIView.animateWithDuration(0, animations: { self.scrollView!.setContentOffset(CGPointZero,animated: true) })
        }
        return true
    }
    override func touchesBegan(touches: Set<UITouch>,
        withEvent event: UIEvent?) {
            self.view.endEditing(true)
    }
    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        self.scrollView.scrollEnabled =  true

        dispatch_async(dispatch_get_main_queue()) {
            UIView.animateWithDuration(0, animations: { self.scrollView!.setContentOffset(CGPointZero,animated: true)

            })
        }
    }
7
A.G

Hier finden Sie eine kostenlose Bibliothek für das Tastaturhandling Keyboard-Handling-in-iPhone-Applications . Sie müssen nur eine Codezeile schreiben:

[AutoScroller addAutoScrollTo:scrollView];

Es ist großartig, mit der Tastatur in Formularen umzugehen

6
user966931

Ich denke, der beste Ansatz ist die Verwendung einer protokollorientierten Programmierung, wenn Sie Swift verwenden.

Als erstes müssen Sie ein KeyboardCapable-Protokoll erstellen, das jedem UIViewController, der diesem entspricht, die Möglichkeit gibt, Tastaturbeobachter zu registrieren und die Registrierung aufzuheben:

import Foundation
import UIKit

protocol KeyboardCapable: KeyboardAnimatable {
    func keyboardWillShow(notification: NSNotification)
    func keyboardWillHide(notification: NSNotification)
}

extension KeyboardCapable where Self: UIViewController {
    func registerKeyboardNotifications() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
    }

    func unregisterKeyboardNotifications() {
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
    }
}

Sie haben das überflüssige KeyboardAnimatable-Schlüsselwort in dem obigen Code festgestellt. Es ist nur der Name des nächsten Protokolls, das wir erstellen müssen:

import Foundation
import UIKit

protocol KeyboardAnimatable {

}

extension KeyboardAnimatable where Self: UIViewController {
    func performKeyboardShowFullViewAnimation(withKeyboardHeight height: CGFloat, andDuration duration: NSTimeInterval) {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.view.frame = CGRectMake(view.frame.Origin.x, -height, view.bounds.width, view.bounds.height)
            }, completion: nil)
    }

    func performKeyboardHideFullViewAnimation(withDuration duration: NSTimeInterval) {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.view.frame = CGRectMake(view.frame.Origin.x, 0.0, view.bounds.width, view.bounds.height)
            }, completion: nil)
    }
}

Dieses KeyboardAnimatable-Protokoll gibt allen UIViewController-Konformaten zwei Methoden, mit denen die gesamte Ansicht nach oben bzw. unten animiert wird.

Okay, wenn KeyboardCapable mit KeyboardAnimatable übereinstimmt, entsprechen alle UIViewController, die KeyboardCapable entsprechen, auch KeyboardAnimatable. Das ist cool.

Lassen Sie uns eine UIViewController-konforme KeyboardCapable sehen, die auf Tastaturereignisse reagiert:

import Foundation
import UIKit

class TransferConfirmViewController: UIViewController, KeyboardCapable {
    //MARK: - LIFE CYCLE       
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        registerKeyboardNotifications()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

        unregisterKeyboardNotifications()
    }

    //MARK: - NOTIFICATIONS
    //MARK: Keyboard
    func keyboardWillShow(notification: NSNotification) {
        let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height
        let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        performKeyboardShowFullViewAnimation(withKeyboardHeight: keyboardHeight, andDuration: animationDuration)
    }

    func keyboardWillHide(notification: NSNotification) {
        let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        performKeyboardHideFullViewAnimation(withDuration: animationDuration)
    }
}

Jetzt reagiert Ihre UIViewController auf Tastaturereignisse und wird in der Folge animiert.

Hinweis: Wenn Sie anstelle von Push oder Pull die Ansicht eine benutzerdefinierte Animation erstellen möchten, müssen Sie benutzerdefinierte Methoden für das Protokoll KeyboardAnimatable definieren oder sie für Funktionen der Funktion KeyboardCapable ausführen. Es liegt an dir.

6
Jorge Ramos

Eine viel elegantere Lösung ist die Verwendung einer UIView-Unterklasse (obwohl dies nicht immer angemessen ist), und alle Unteransichten für den Frame-Wechsel eines Elternteils neu berechnen (und seien Sie intelligent: nur neu berechnen, wenn sich die neue Frame-Größe geändert hat, dh verwendet wird) CGRectEqualToRect, um den neuen Frame zu vergleichen, wenn Sie setFrame überschreiben und VOR dem Aufruf von [super setFrame:frame_]). Der einzige Haken dabei ist, dass das UIViewController, das Sie verwenden möchten, wahrscheinlich Tastaturereignisse hören sollte (oder Sie könnten es im UIView selbst tun, um die Kapselung zu erleichtern). Aber nur UIKeyboardWillShowNotification und UIKeyboardWillHideNotification. Dies ist nur so, dass es glatt aussieht (wenn Sie darauf warten, dass CG es anruft, erhalten Sie einen Moment der Abgeschlagenheit).

Dies hat den Vorteil, dass eine UIView-Unterklasse erstellt wird, die ohnehin das Richtige tut.

Die naive Implementierung wäre, drawRect: (nicht) zu überschreiben. Besser wäre es, layoutSubviews zu verwenden (und dann in UIViewController oder was auch nicht. Sie können [view setNeedsLayout] in einer SINGLE-Methode aufrufen, die entweder show oder aufgerufen wird verbergen).

Diese Lösung vermeidet die Hardcodierung eines Tastatur-Offsets (der sich ändert, wenn sie nicht aufgeteilt sind usw.). Dies bedeutet auch, dass Ihre Ansicht eine Unteransicht vieler anderer Ansichten sein kann und dennoch ordnungsgemäß reagiert.

Hardcode so etwas nicht, wenn es keine andere Lösung gibt. Das Betriebssystem gibt Ihnen genug Informationen, wenn Sie alles richtig gemacht haben, dass Sie nur intelligent neu zeichnen müssen (basierend auf Ihrer neuen frame-Größe). Das ist viel sauberer und so wie du sollte Dinge tun. (Es kann jedoch einen noch besseren Ansatz geben.)

Prost.

5
Matt Weaver

Es ist sehr einfach, einfach folgenden Code in Ihre Klasse einzufügen und bei Bedarf anzupassen.

-(void)textFieldDidBeginEditing:(UITextField *)textField {
     //Show Keyboard
     self.view.frame = CGRectMake(self.view.frame.Origin.x,
                              self.view.frame.Origin.y-50,
                              self.view.frame.size.width,
                              self.view.frame.size.height);   
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
     // Hide keyboard
     self.view.frame = CGRectMake(self.view.frame.Origin.x,
                              self.view.frame.Origin.y+50,
                              self.view.frame.size.width,
                              self.view.frame.size.height); 
}

Sie können dies auch tun, indem Sie Textfeld-Delegatmethoden verwenden. Überprüfen Sie den Code unten. Es funktioniert für mich, wenn das Textfeld in der Bildlaufansicht platziert wird.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
     if(textField == answer)
    {   
         CGPoint cPoint = textField.frame.Origin;
         [scrollView setContentOffset:CGPointMake(0, cPoint.y - 100) animated:YES];
    }
}

Hinweis: Sie müssen den Wert von cPoint.y - 100 entsprechend Ihrer Ansicht ändern.

4
Ganesh Guturi

Hier ist meine Version mit Autolayout:

Die Idee ist nur, Ihre Ansicht, die Textfelder/Textansicht enthält, in eine UIScrollView einzubetten, eine Einschränkung von unten auf den Übersichtsbereich festzulegen, einen Ausgang zu erstellen und ihn anhand der Tastaturhöhe mithilfe von Benachrichtigungen zu aktualisieren. Dies basiert auf dem Beispiel von Apple hier und technischer Hinweis von Apple zu UIScrollView mit AutoLayout hier .

1) Betten Sie Ihre Ansicht V in eine UIScrollView S: Wenn Sie bereits Konstanten und Unteransichten festgelegt haben, können Sie Ihre Ansicht und Unteransichten in die Ansicht des ViewControllers kopieren/einfügen, sie dann über das Menü Editor -> Einbetten einbetten und schließlich löschen die kopierten Ansichten.)

2) Legen Sie die folgenden Bedingungen fest:

  • S nach oben Layouthilfe: 0
  • S nach unten Layout Guide: 0
  • S führt zum Überblick: 0
  • S nach Übersehen: 0

  • V top Platz zum Superview: 0

  • V unterer Raum zum Übersehen: 0
  • V hinter dem Leerzeichen bis zum Übersichtsfenster: 0
  • V führender Platz zum Überblick: 0

  • V gleich Breite zu S

  • Letzte Untersicht für Untersicht: 20

3) Erstellen Sie einen Auslass aus der neuesten Einschränkung für Ihren View-Controller

4) Verwenden Sie den folgenden Code:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomSpaceToContentView;

// ...

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    // ...

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

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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Handle keyboard

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

    self.bottomSpaceToContentView.constant = kBottomMargin + kbSize.height;
    [self.view layoutIfNeeded];
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    self.bottomSpaceToContentView.constant = kBottomMargin;
    [self.view layoutIfNeeded];
}

Und tadaaaaa, es funktioniert!

4
dulgan

Es gibt viele Antworten, die den Ansatz erklären. Ich habe den gleichen Ansatz gewählt, aber die Implementierung ist nicht gut.

Hier ist die Basis Idee . Ich habe Änderungen an der keyboardWasShown-Methode vorgenommen.

{
// Obtain keyboard Info
NSDictionary* info = [notification userInfo];
CGRect keyboardRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil];

// Obtain ScrollView Info w.r.t. top View
CGRect scrollViewRect = [self.view convertRect:self.scrollView.frame fromView:nil];

// Depending upon your screen Ui, Scroll View's bottom Edge might be at some offset from screen's bottom
// Calculate the exact offset
int scrollViewBottomOffset = self.view.frame.size.height - (scrollViewRect.Origin.y + scrollViewRect.size.height);
int heightToBeAdjusted = keyboardRect.size.height - scrollViewBottomOffset;


// We may also need to consider the Insets if already present with ScrollView. Let's keep it simple for now
// But we should store these, so that we can restore the Insets when Keyboard is gone
// origInsets = self.scrollView.contentInset;

// Set the new Insets for ScrollView
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, heightToBeAdjusted, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;

// Visible frame (not overlapped by Keyboard)
CGRect visibleFrame = self.view.frame;
visibleFrame.size.height -= keyboardRect.size.height;

// Get the Rect for Textfield w.r.t self.view
CGRect activeFieldFrame = self.activeField.frame;
activeFieldFrame = [self.view convertRect:activeFieldFrame fromView:self.scrollView];

// Check if the TextField is Visible or not
if (!CGRectContainsRect(visibleFrame, activeFieldFrame) ) {
    // Scroll to make it visible but for scrolling use the activeField frame w.r.t. to scroll View
    [self.scrollView scrollRectToVisible:self.activeField.frame animated:YES];
}

}

Fügen Sie diese Methode hinzu, um das activeField zu initialisieren

- (IBAction)textFieldDidBeginEditing:(UITextField *)sender
{
self.activeField = sender;
}
4
vinksharma

Dies ist eine geräteunabhängige Offsetberechnung. Ruft die überlappte Höhe zwischen Tastatur und Textfeld ab:

func keyboardShown(notification: NSNotification) {
    let info  = notification.userInfo!
    let value: AnyObject = info[UIKeyboardFrameEndUserInfoKey]!

    let rawFrame = value.CGRectValue
    let keyboardFrame = view.convertRect(rawFrame, fromView: nil)

    let screenHeight = UIScreen.mainScreen().bounds.size.height;
    let Ylimit = screenHeight - keyboardFrame.size.height
    let textboxOriginInSuperview:CGPoint = self.view.convertPoint(CGPointZero, fromCoordinateSpace: lastTextField!)

    self.keyboardHeight = (textboxOriginInSuperview.y+self.lastTextField!.frame.size.height) - Ylimit

    if(self.keyboardHeight>0){
        self.animateViewMoving(true, moveValue: keyboardHeight!)
    }else{
        keyboardHeight=0
    }
}

keyBoardHeight ist der Versatz.

https://github.com/michaeltyson/TPKeyboardAvoiding Laden Sie diese Datei herunter und fügen Sie eine benutzerdefinierte Klasse hinzu. Wenn Sie diese Option in Ihrer Tabellenansicht verwenden, werden alle Dinge verwaltet Tastatur zu vermeiden

4
anand madhav

hier ist eine UITextfield-Kategorie (und andere ähnliche Felder), die ich vorgenommen habe, um das Textfeld von der Tastatur zu entfernen. Sie sollten es in der Lage sein, dieses in Ihrem View-Controller abzulegen. Der gesamte Bildschirm wird nach oben verschoben, sodass sich das aktuelle Textfeld mit Animationen über der Tastatur befindet

#import "UIView+avoidKeyboard.h"
#import "AppDelegate.h"

@implementation UIView (avoidKeyboard)

- (void) becomeFirstResponder {

if(self.isFirstResponder)
    return;

[super becomeFirstResponder];

if ([self isKindOfClass:[UISearchBar class]] ||
    [self isKindOfClass:[UITextField class]] ||
    [self isKindOfClass:[UITextView class]])
{
    AppDelegate *appDelegate    = [UIApplication sharedApplication].delegate;

    CGRect screenBounds         = appDelegate.window.frame;

    CGFloat keyboardHeight;
    CGFloat keyboardY;
    CGFloat viewsLowestY;
    CGPoint Origin              = [self.superview convertPoint:self.frame.Origin toView:appDelegate.window]; //get this views Origin in terms of the main screens bounds

    if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])){ //the window.frame doesnt take its orientation into account so if its sideways we must use the x value of the Origin instead of the y
        keyboardHeight          = 216;
        keyboardY               = screenBounds.size.height  - keyboardHeight; //find the keyboards y coord relative to how much the main window has moved up
        viewsLowestY            = Origin.y + self.frame.size.height; //find the lowest point of this view
    }
    else {
        keyboardHeight          = 162;
        keyboardY               = screenBounds.size.width  - keyboardHeight;
        viewsLowestY            = Origin.x + self.frame.size.height;
    }

    CGFloat difference          = viewsLowestY - keyboardY + 20; //find if this view overlaps with the keyboard with some padding

    if (difference > 0){ //move screen up if there is an overlap

        [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{

            CGRect frame = appDelegate.window.frame;

            if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])){
                frame.Origin.y -= difference;
            }
            else {
                frame.Origin.x -= difference;
            }
            appDelegate.window.frame = frame;
        }
        completion:nil];
    }
}
}

//look at appDelegate to see when the keyboard is hidden

@end

Fügen Sie in Ihrer appDelegate diese Funktion hinzu

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardHides:) name:UIKeyboardWillHideNotification object:nil]; //add in didFinishLaunchingWithOptions

...

- (void)keyboardHides:(NSNotification *)notification
{
    [UIView animateWithDuration:0.3 animations:^{
        [window setFrame: CGRectMake(0, 0, window.frame.size.width, window.frame.size.height)];
    } completion:nil];
}
4
Fonix

Bitte folgen Sie diesen Schritten. 

1) Deklarieren Sie die folgende Variable in der .h-Datei.

  {      
         CGFloat animatedDistance;
  }

2) Deklarieren Sie die folgenden Konstanten in der .m-Datei.

  static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
  static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
  static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
  static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
  static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;

3) Verwenden Sie den UITextField-Delegaten, um die Tastatur nach oben/unten zu verschieben.

  -(void) textFieldDidBeginEditing:(UITextField *)textField
  { 
         if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
         {
               CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
               CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];

               CGFloat midline = textFieldRect.Origin.y + 0.5 * textFieldRect.size.height;
               CGFloat numerator =
    midline - viewRect.Origin.y
    - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
               CGFloat denominator =
    (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
    * viewRect.size.height;
               CGFloat heightFraction = numerator / denominator;

               if (heightFraction < 0.0)
               {
                     heightFraction = 0.0;
               }
               else if (heightFraction > 1.0)
               {
                     heightFraction = 1.0;
               }

               UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];
               if (orientation == UIInterfaceOrientationPortrait)
               {
                     animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
               }
               else
               {
                     animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
               }

               CGRect viewFrame = self.view.frame;
               viewFrame.Origin.y -= animatedDistance;

               [UIView beginAnimations:nil context:NULL];
               [UIView setAnimationBeginsFromCurrentState:YES];
               [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

               [self.view setFrame:viewFrame];

               [UIView commitAnimations];
       }
  }

  -(void) textFieldDidEndEditing:(UITextField *)textField
  {
       if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
       {
             CGRect viewFrame = self.view.frame;
             viewFrame.Origin.y += animatedDistance;

             [UIView beginAnimations:nil context:NULL];
             [UIView setAnimationBeginsFromCurrentState:YES];
             [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

             [self.view setFrame:viewFrame];

             [UIView commitAnimations];
       }
 }
3

Ich wickle alles in eine Klasse. Rufen Sie einfach diese Codezeilen auf, wenn Ihr Viewcontroller geladen ist:

- (void)viewDidLoad {
    [super viewDidLoad];
    KeyboardInsetScrollView *injectView = [[KeyboardInsetScrollView alloc] init];
    [injectView injectToView:self.view withRootView:self.view];
}

Hier ist ein Link zum Beispielprojekt:
https://github.com/caohuuloc/KeyboardInsetScrollView

3
Cao Huu Loc

Vor kurzem befand ich mich bei der Arbeit an einer Messaging-App in einem ähnlichen Szenario. Ich habe ein benutzerdefiniertes UIView erstellt, das am oberen Rand der Tastatur haftet und das meiste, was Sie benötigen, automatisch ausführt

MessageComposerView

http://www.thegameengine.org/wp-content/uploads/2013/11/message_composer_quad_1.jpg

Die Idee hinter diesem Projekt war, etwas zu erstellen, das der iMessage-Kompositionsansicht AKA ähnelt:

  • klebt an der Oberseite der Tastatur und bewegt sich an die Unterseite des Bildschirms, wenn die Tastatur geschlossen wird
  • behandelt Änderungen im Text
  • behandelt Drehungen

Um die Größe Ihres UIScrollView zu ändern oder neu zu konfigurieren, verwenden Sie die folgende optionale Delegierungsmethode:

- (void)messageComposerFrameDidChange:(CGRect)frame withAnimationDuration:(float)duration;

Sie wird aufgerufen, wenn der Frame geändert (in der Größe geändert, neu positioniert, gedreht) wird, und liefert auch die Animationsdauer. Sie können diese Informationen verwenden, um die Größe des Rahmens und der Inhalte Ihres UIScrollView nach Bedarf zu ändern.

3
alexgophermix

Fügen Sie diese einfach Ihrer Pod-Datei hinzu -> pod 'IQKeyboardManager'

Das ist es, alle Tastaturen und Scrollviews und alles!

Sie müssen nichts kodieren, könnte keine bessere Lösung finden!

Es hat eine Erweiterung, die die Anzeige von Textfeldern, die Bildschirmverschiebung sowie die nächsten und vorherigen Pfeile übernimmt, wenn mehrere Textfelder vorhanden sind.

Es hat auch eine benutzerdefinierte Schaltfläche, die entfernt werden kann.

Link -> https://github.com/hackiftekhar/IQKeyboardManager

3
Kakshil Shah

Ich habe festgestellt, dass dies die beste Lösung ist. Folgen Sie dem nachstehenden Code: 

Befestigen Sie das unten stehende an Ihre Vertical Space - Bottom Layout Guide - TextField-Einschränkung. 

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewBottomConst;

Zweitens fügen Sie Beobachter für Tastaturbenachrichtigungen hinzu.

- (void)observeKeyboard {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

Fügen Sie dies Ihrer viewDidLoad hinzu. 

[self observeKeyboard]; 

Schließlich die Methoden, mit denen Tastaturänderungen vorgenommen werden.

- (void)keyboardWillShow:(NSNotification *)notification {
//THIS WILL MAKE SURE KEYBOARD DOESNT JUMP WHEN OPENING QUICKTYPE/EMOJI OR OTHER KEYBOARDS.
kbHeight = 0;
height = 0;
self.textViewBottomConst.constant = height;
self.btnViewBottomConst.constant = height;

    NSDictionary *info = [notification userInfo];
    NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];

    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [kbFrame CGRectValue];

    CGRect finalKeyboardFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];

    int kbHeight = finalKeyboardFrame.size.height;

    int height = kbHeight + self.textViewBottomConst.constant;

    self.textViewBottomConst.constant = height;

    [UIView animateWithDuration:animationDuration animations:^{
        [self.view layoutIfNeeded];
    }];
}

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

    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    self.textViewBottomConst.constant = 10;

    [UIView animateWithDuration:animationDuration animations:^{
        [self.view layoutIfNeeded];
    }];
}
3
Manesh

Eine viel einfachere und dennoch verallgemeinerte Methode, genau wie Apple, indem die Höhe der Tastaturen berücksichtigt wird. Dies ist sehr hilfreich, wenn wir eine benutzerdefinierte Symbolleiste auf der Tastatur verwenden Obwohl Apples Ansatz here einige Probleme hat.

Hier ist meine Herangehensweise (leicht modifizierter Weg von Apple) - 

// UIKeyboardDidShowNotification
- (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);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

// UIKeyboardWillHideNotification
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}
3
Sam92

Ich weiß, dass dies zu spät ist, aber ich wollte den zukünftigen Besuchern vor allem meine Art und Weise mitteilen. Viele gute Methoden wurden geteilt, aber es hat mir nicht gefallen, wie die Benutzeroberfläche total schlecht wird. Es gibt eine einfache Methode, die zwei Teile umfasst: -

  1. Fügen Sie das TextField hinzu, und wenn Sie möchten, dass es während der Bearbeitung über der Tastatur angezeigt wird, können Sie es einer Ansicht hinzufügen, so dass diese der Ansicht untergeordnet werden. Und dann wird es leicht sein, das Aussehen beizubehalten und die Benutzeroberfläche nicht zu beeinträchtigen.
  2. Verwenden Sie das großartige WerkzeugCGAffineTransform(TranslationX: x, TranslationY: y), um die erstellte Ansicht über die Tastatur zu verschieben. 

Ich weiß, dass es sehr einfach erscheint, aber es ist wirklich effektiv und ordentlich .  enter image description here

3
Badr

Eine einfache Lösung, die den UIViewController erweitert

https://github.com/damienromito/VisibleFormViewController

enter image description here

3
Damien Romito

Einfache Lösung und mit der neuesten Animations-API. Wenn Sie den Origin.y um 215 ändern, können Sie ihn an den für Sie geeigneten Wert anpassen.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    if (self.view.frame.Origin.y >= 0) {

        [UIView animateWithDuration:0.5 animations:^{
           self.view.frame = CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y-215, self.view.frame.size.width, self.view.frame.size.height);
       }];
   }
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    if (self.view.frame.Origin.y < 0) {
        [UIView animateWithDuration:0.5 animations:^{
           self.view.frame = CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y+215, self.view.frame.size.width, self.view.frame.size.height);
        }];

    }
}
2
Vidhur

Ich möchte die Antwort von @sumanthkodi erweitern.

Wie einige Leute bereits sagten, funktioniert sein Ansatz in neueren Implementierungen nicht, da sich der UIView nicht bewegt, wenn Sie constraints verwenden.

Ich habe den Code wie folgt bearbeitet (und auf Swift 2.0 portiert) und hoffe, dass er einigen Leuten hilft:


1) Referenzieren Sie die vertikale Einschränkung der Ansicht, die Sie nach oben verschieben möchten:

@IBOutlet var viewConstraint: NSLayoutConstraint!

Stellen Sie sicher, dass Sie diese Variable in Ihrem Storyboard mit der Einschränkung referenzieren.

2) Fügen Sie den Delegierten hinzu und implementieren Sie die Listener. Dies ist die gleiche Implementierung wie zuvor:

class YourViewController: UIViewController, UITextFieldDelegate {

    ...

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

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

    ...

}

3) Fügen Sie Ihre Animationsmethode animateTextField zur YourViewController-Klasse hinzu. Legen Sie den temporären Einschränkungswert nach Bedarf fest.

func animateTextField(textfield: UITextField, up: Bool) {

    let originalConstraint = 50
    let temporaryConstraint = 0
    let movementDuration = 0.3

    let constraint = CGFloat(up ? temporaryConstraint : originalConstraint)

    containerViewConstraint.constant = constraint
    UIView.animateWithDuration(movementDuration) {
        self.view.layoutIfNeeded()
    }

}
2
andreas

Das wird perfekt funktionieren. Die Bildlaufansicht wird durch die Textfeldposition automatisch angepasst

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.25;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;
@interface LoginVC ()
{
  CGFloat animatedDistance;
   CGRect viewFrameKey;
}

 //In ViewDidLoad
   viewFrameKey=self.view.frame;



- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.Origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.Origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
    heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
    heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
    orientation == UIInterfaceOrientationPortraitUpsideDown)
{
    animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
    animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.Origin.y -= animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrameKey];
[UIView commitAnimations];
}
2
Mahesh reddy

Ich habe gerade diese Klasse gefunden:

https://github.com/OliverLetterer/SLScrollViewKeyboardSupport

Und bisher funktioniert es auf dem iPhone sehr gut, einschließlich Animationen und korrektem Offset.

Um es zu verwenden, fügen Sie einfach viewDidLoad hinzu:

self.support = [[SLScrollViewKeyboardSupport alloc] initWithScrollView:self.scrollView];
2
Sebastian Roth

Eine sehr leichte Lösung könnte mit KeyboardAnimator sein. 

projekt hat die Beispielimplementierung erhalten, die Dokumentation ist noch in Bearbeitung ...

Bestimmungsgemäße Verwendung :: Es gibt eine spezielle Implementierung für UITextField & UITextView

Limitation :: Es ist voll auf Ziel-c, die Swift-Version wird bald verfügbar sein.

2
Ratul Sharker

Dieser Teil des Codes berechnet anhand der Höhe der Tastatur und der Tiefe des Textfelds, wie viel Bewegung erforderlich ist. Denken Sie daran, UITextFieldDelegate in Ihre Kopfzeile zu delegieren und zu erben.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_tbxUsername resignFirstResponder];
    [_tbxPassword resignFirstResponder];
}

- (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
{
    int animatedDistance;
    int moveUpValue = textField.frame.Origin.y+ textField.frame.size.height;
    UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];
    if (orientation == UIInterfaceOrientationPortrait ||
        orientation == UIInterfaceOrientationPortraitUpsideDown)
    {

        animatedDistance = 236-(460-moveUpValue-5);
    }
    else
    {
        animatedDistance = 182-(320-moveUpValue-5);
    }

    if(animatedDistance>0)
    {
        const int movementDistance = animatedDistance;
        const float movementDuration = 0.3f;
        int movement = (up ? -movementDistance : movementDistance);
        [UIView beginAnimations: nil context: nil];
        [UIView setAnimationBeginsFromCurrentState: YES];
        [UIView setAnimationDuration: movementDuration];
        self.view.frame = CGRectOffset(self.view.frame, 0, movement);
        [UIView commitAnimations];
    }
}

Delegieren Sie bei ViewDidLoad hinzu

_tbxUsername.delegate = self;
_tbxPassword.delegate = self;
2
teapeng
  1. Laden Sie TPKeyBoardAvoiding von diesem Link herunter: https://github.com/michaeltyson/TPKeyboardAvoiding
  2. Erweitern Sie den gezippten Ordner und suchen Sie den Ordner TPKeyboardAvoiding.
  3. Wählen Sie alle .h- und .m-Dateien aus, und legen Sie sie in Ihrem Projekt ab. Stellen Sie sicher, dass Elemente kopiert werden, wenn dies erforderlich ist.
  4. Ziehen Sie eine UIScrollView per Drag & Drop in StoryBoard und verknüpfen Sie sie mit TPKeyboardAvoidingScrollView.
  5. Jetzt können Sie Benutzeroberflächenelemente oben in der Bildlaufansicht hinzufügen. Beachten Sie, dass diese Klasse die UI-Elemente auch nach dem Ziehen des ScrollView-Objekts erkennt.

Auf Ihrem ViewController:

@IBOutlet weak var usernameTextfield: UITextField!
@IBOutlet weak var passwordTextfield: UITextField!
@IBOutlet weak var loginScrollView: UIScrollView!


override func viewWillAppear(animated: Bool) {
        loginScrollView.scrollEnabled =  false
    }

TextFeld-Delegaten hinzufügen.

//MARK:- TEXTFIELD METHODS
func textFieldShouldReturn(textField: UITextField) -> Bool
{
    if (usernameTextfield.resignFirstResponder())
    {
        passwordTextfield.becomeFirstResponder()
    }
    textField.resignFirstResponder();
    loginScrollView!.setContentOffset(CGPoint.zero, animated: true);
    loginScrollView.scrollEnabled =  false
    return true
}
func textFieldDidBeginEditing(textField: UITextField)
{
    loginScrollView.scrollEnabled =  true

    if (textField.tag  == 1 && (device == "iPhone" || device == "iPhone Simulator" || device == "iPod touch"))
    {
        let scrollPoint:CGPoint = CGPointMake(0, passwordTextfield.frame.Origin.y/6.4);
        loginScrollView!.setContentOffset(scrollPoint, animated: true);

    }
    else if (textField.tag  == 2 && (device == "iPhone" || device == "iPhone Simulator" || device == "iPod touch"))
    {
        let scrollPoint:CGPoint = CGPointMake(0, passwordTextfield.frame.Origin.y/6.0);
        loginScrollView!.setContentOffset(scrollPoint, animated: true);
    }
}
func textFieldDidEndEditing(textField: UITextField)
{
    loginScrollView!.setContentOffset(CGPointZero,animated: true);
}
2
A.G

Scrollansicht in Ansicht einstellen  

  - (void)textFieldDidBeginEditing:(UITextField *)textField
    {
     CGPoint point;
    if(textField == txtEmail){
      // -90 is for my you can change as per your postion
      point = CGPointMake(0, textField.frame.Origin.y - 90);
    }
    else if (textField == txtContact){
      point = CGPointMake(0, textField.frame.Origin.y - 90);
    }
      [scrollV setContentOffset:point animated:YES];
    }
2
seggy

Bitte fügen Sie diese Zeilen in die Textfeld-Delegatenmethode ein, um im iPad nach oben zu scrollen. 

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

    CGPoint pt;
    CGRect rc = [textField bounds];
    rc = [textField convertRect:rc toView:scrlView];
    pt = rc.Origin;
    pt.x = 0;
    pt.y -= 100;

    [scrlView setContentOffset:pt animated:YES];

    scrlView.contentSize = CGSizeMake(scrlView.frame.size.width, button.frame.Origin.y+button.frame.size.height + 8 + 370);
}
2
jayesh mardiya

Versuchen Sie die IQKeyboard-Bibliothek.

Dadurch wird das Textfeld automatisch nach oben verschoben.

2
User511

Dies kann einfach mit untersten Codezeilen unter Verwendung von Einschränkungen erreicht werden

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillHide:)
                                                     name:UIKeyboardWillHideNotification
                                                   object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    [self adjustTextViewByKeyboardState:YES keyboardInfo:[notification userInfo]];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    [self adjustTextViewByKeyboardState:NO keyboardInfo:[notification userInfo]];
}

- (void)viewDidDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super viewDidDisappear:animated];
}

- (void)adjustTextViewByKeyboardState:(BOOL)showKeyboard keyboardInfo:(NSDictionary *)info {
    CGRect keyboardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat height = keyboardFrame.size.height;
    self.constraintToAdjust.constant = height;        UIViewAnimationCurve animationCurve = [info[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
    UIViewAnimationOptions animationOptions = UIViewAnimationOptionBeginFromCurrentState;
    if (animationCurve == UIViewAnimationCurveEaseIn) {
        animationOptions |= UIViewAnimationOptionCurveEaseIn;
    }
    else if (animationCurve == UIViewAnimationCurveEaseInOut) {
        animationOptions |= UIViewAnimationOptionCurveEaseInOut;
    }
    else if (animationCurve == UIViewAnimationCurveEaseOut) {
        animationOptions |= UIViewAnimationOptionCurveEaseOut;
    }
    else if (animationCurve == UIViewAnimationCurveLinear) {
        animationOptions |= UIViewAnimationOptionCurveLinear;
    }
    [UIView animateWithDuration:[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue] delay:0 options:animationOptions animations:^{
        [self.view layoutIfNeeded];
    }                completion:nil];
}
2
Rajesh
  • Wenn das Textfeld nicht ganz oder teilweise ausgeblendet ist, sollten wir nichts ändern.
  • Wir sollten den exakten Schnittbereich (Tastaturrahmen und Rahmen des Textfelds) berechnen, der ausgeblendet ist, und dann den Rahmen der Ansicht ändern.

  • Hier gebe ich ein vollständiges Beispiel.

    3 für variabel erklären

#define PADDING 10

@interface PKViewController ()
      @property (nonatomic, assign) CGRect originalViewFrame; //original view's frame
      @property (nonatomic, strong) UITextField *activeTextField; // current text field
      @property (nonatomic, assign) CGRect keyBoardRect; // covered area by keaboard
     @end

Speichern Sie den Originalrahmen

- (void)viewDidLoad {
    [super viewDidLoad];
    _originalViewFrame = self.view.frame;
}

Fügen Sie Ihren View-Controller als Beobachter für die Tastaturbenachrichtigung hinzu

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

Beobachter entfernen

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Speichern Sie den von der Tastatur abgedeckten Bereich, wenn diese angezeigt wird, und setzen Sie sie auf CGRectZero, wenn sie nicht mehr angezeigt wird 

- (void)keyboardWasShown:(NSNotification *)notification{
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    _keyBoardRect = CGRectMake(0, _originalViewFrame.size.height - keyboardSize.height, keyboardSize.width, keyboardSize.height);
    [self moveTextFieldUP];

}
- (void) keyboardWillHide:(NSNotification *)notification{
    _keyBoardRect = CGRectZero;
    [self setDefaultFrame];
}

Speichern Sie das aktive Textfeld 

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    _activeTextField = textField;
//When keyboard is already present but the textfield is hidden. Case:When return key of  keyboard makes the next textfield as first responder
    if (!CGRectIsEmpty(_keyBoardRect)) { 
        [self moveTextFieldUP];
    }
    return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    return YES;
}

Jetzt sollten wir den Rahmen der Ansicht ändern

- (void)moveTextFieldUP{
    CGRect virtualTextFieldRect = CGRectMake(0, self.view.frame.Origin.y, _activeTextField.frame.size.width, _activeTextField.frame.Origin.y+_activeTextField.frame.size.height);
    if (CGRectIntersectsRect(_keyBoardRect, virtualTextFieldRect)) {
        CGRect intersectRect = CGRectIntersection(_keyBoardRect, virtualTextFieldRect);
        CGFloat newY = _originalViewFrame.Origin.y - intersectRect.size.height;
        CGFloat newHeight = _originalViewFrame.size.height + intersectRect.size.height;
        CGRect newFrame = CGRectMake(0, newY-PADDING, _originalViewFrame.size.width, newHeight+PADDING);
        [UIView animateWithDuration:0.3 animations:^{
            [self.view setFrame:newFrame];
        }];

        NSLog(@"Intersect");
    }
}
- (void)setDefaultFrame {
    [UIView animateWithDuration:0.3 animations:^{
        [self.view setFrame:_originalViewFrame];
    }];
}
2
PKN

Viele Antworten hier, aber das funktioniert und ist viel kürzer als die meisten:

- (void)textFieldDidBeginEditing:(UITextField *)sender
{
    UIScrollView *scrollView = (UIScrollView *)self.view; // assuming this method is pasted into the UIScrollView's controller
    const double dontHardcodeTheKeyboardHeight = 162;
    double textY = [sender convertPoint:CGPointMake(0, 0) toView:scrollView].y;
    if (textY - scrollView.contentOffset.y + sender.frame.size.height > self.view.frame.size.height - dontHardcodeTheKeyboardHeight)
        [scrollView setContentOffset:CGPointMake(0.0, textY - 10) animated:YES];
}
2
Nestor

Kann leicht und automatisch durchgeführt werden, wenn sich dieses Textfeld in einer Tabellenzelle befindet (auch wenn table.scrollable = NO ist).

  • ANMERKUNG: Die Position und Größe der Tabelle muss angemessen sein Beispiel:
    • wenn die y-Position der Tabelle 100 vom unteren Rand der Ansicht aus gezählt wird, überlappt die 300-Höhen-Tastatur die gesamte Tabelle.
    • wenn die Höhe der Tabelle = 10 ist und das Textfeld darin 100 angezeigt werden muss, wenn die Tastatur angezeigt wird, um sichtbar zu sein, befindet sich dieses Textfeld außerhalb der Tabellengrenze. 
2
samthui7
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField {

  [self slideUp];
   return YES;
}

-(BOOL) textFieldShouldEndEditing:(UITextField *)textField {

    [self slideDown];
   return YES;
}

#pragma mark - Slide Up and Down animation

- (void) slideUp {
    [UIView beginAnimations:nil context:nil];
    layoutView.frame = CGRectMake(0.0, -70.0, layoutView.frame.size.width, layoutView.frame.size.height);

    [UIView commitAnimations];
}


- (void) slideDown {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelay: 0.01]; 
    layoutView.frame = CGRectMake(0.0, 0.0, layoutView.frame.size.width, layoutView.frame.size.height);
    [UIView commitAnimations];
}

Obwohl dieser Thread über genügend Antworten verfügt, möchte ich einen viel einfacheren, aber verallgemeinerten Weg vorschlagen, genauso wie Apple dies tut, indem er die Höhe der Tastaturen berücksichtigt. Dies ist sehr hilfreich, wenn wir eine benutzerdefinierte Symbolleiste auf der Tastatur verwenden hier hat wenige Probleme.

Hier ist meine Herangehensweise (leicht modifizierter Weg von Apple) - 

// 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);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

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

es ist einfach:-

In TextFieldDidBeginEditing: -

self.view.frame=CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y-150, self.view.frame.size.width, self.view.frame.size.height);

In TextFieldShouldEndEditing: -

self.view.frame=CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y+150, self.view.frame.size.width, self.view.frame.size.height);
1
dreamBegin

Mit IQKeyboardManager scrollen UITextField und UITextView automatisch, wenn die Tastatur angezeigt wird. Git link: https://github.com/hackiftekhar/IQKeyboardManager .

pod: Pod 'IQKeyboardManager' # iOS8 und höher

pod 'IQKeyboardManager', '3.3.7' # iOS7

1

Einfache Lösung für Scrollview mit TextFields ist unten. Keine Einschränkungen oder aktives Textfeld usw. 

 override func viewWillAppear(_ animated: Bool){
        super.viewWillAppear(animated)
        registerForKeyboardNotifications();


    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        deregisterFromKeyboardNotifications();
    }
    //MARK:- KEYBOARD DELEGATE METHODS
        func registerForKeyboardNotifications(){
            //Adding notifies on keyboard appearing
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        }
        func deregisterFromKeyboardNotifications(){
            //Removing notifies on keyboard appearing
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        }
        func keyboardWasShown(notification: NSNotification){

            var info = notification.userInfo!
            let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
            var contentInset:UIEdgeInsets = self.scrRegister.contentInset
            contentInset.bottom = (keyboardSize?.height)!
            scrRegister.contentInset = contentInset


        }
        func keyboardWillBeHidden(notification: NSNotification)
        {
            var contentInset:UIEdgeInsets = self.scrRegister.contentInset
            contentInset.bottom = 0
            scrRegister.contentInset = contentInset

        }
1
Jaydeep Vyas

Bitte befolgen Sie diese Schritte, es kann hilfreich sein . Legen Sie eine Ansicht und dann Ihr Textfeld in dieser Ansicht fest, und erkennen Sie das Ereignis per Delegat, wenn Ihre Tastatur hochgefahren wird. Animieren Sie zu diesem Zeitpunkt die Ansicht nach oben (Sie können eine Position zuweisen.) (auch für diese Ansicht), dann würde Ihre Ansicht zu dieser Position gehen. Machen Sie dasselbe, um die Ansicht nach unten zu animieren.

Vielen Dank

1
user1240409

Swift 3.0-Version von Apples Tastaturverwaltungscode ist hier: FloatingTF Im folgenden Code wird ein Textfeld auf Materialdesign-Basis in iOS verwendet.

import UIKit
class SignupViewController: UIViewController, UITextFieldDelegate {

    //MARK: - IBOutlet:
@IBOutlet weak var emailTF: FloatingTF!
@IBOutlet weak var passwordTF: FloatingTF!
@IBOutlet weak var dobTF: FloatingTF!

@IBOutlet weak var scrollView: UIScrollView!

//MARK: - Variable:
var activeTextField: UITextField!

//MARK: - ViewController Lifecycle:
override func viewDidLoad() {
    super.viewDidLoad()        
    emailTF.delegate = self
    passwordTF.delegate = self
    dobTF.delegate = self 
}
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    registerKeyboardNotifications()
}
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

   deRegisterKeyboardNotifications()
}

//MARK: - Keyboard notification observer Methods
fileprivate func registerKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(SignupViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(SignupViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
fileprivate func deRegisterKeyboardNotifications() {
    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: self.view.window)
    NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: self.view.window)
}
func keyboardWillShow(notification: NSNotification) {

    let info: NSDictionary = notification.userInfo! as NSDictionary
    let value: NSValue = info.value(forKey: UIKeyboardFrameBeginUserInfoKey) as! NSValue
    let keyboardSize: CGSize = value.cgRectValue.size
    let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.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: CGRect = self.view.frame
    aRect.size.height -= keyboardSize.height
    let activeTextFieldRect: CGRect? = activeTextField?.frame
    let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.Origin
    if (!aRect.contains(activeTextFieldOrigin!)) {
        scrollView.scrollRectToVisible(activeTextFieldRect!, animated:true)
    }    }

func keyboardWillHide(notification: NSNotification) {
    let contentInsets: UIEdgeInsets = .zero
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets
}

//MARK: - UITextField Delegate Methods
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if textField == emailTF {
        passwordTF.becomeFirstResponder()
    }
    else if textField == passwordTF {
        dobTF.becomeFirstResponder()
    }
    else {
        self.view.endEditing(true)
    }
    return true
}

func textFieldDidBeginEditing(_ textField: UITextField) {
    activeTextField = textField
    scrollView.isScrollEnabled = true
}

func textFieldDidEndEditing(_ textField: UITextField) {
    activeTextField = nil
    scrollView.isScrollEnabled = false
}
}
1
abhi1992

Das hat für mich funktioniert:

func setupKeyboardNotifications() {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWasShown:"), name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillBeHidden:"), name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWasShown(aNotification:NSNotification) {
    let info = aNotification.userInfo
    let infoNSValue = info![UIKeyboardFrameBeginUserInfoKey] as NSValue
    let kbSize = infoNSValue.CGRectValue().size
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(0.3)
    var rect : CGRect = self.view.frame
    rect.size.height -= kbSize.height

    self.view.frame = rect
    UIView.commitAnimations()
}

func keyboardWillBeHidden(aNotification:NSNotification) {
    let info = aNotification.userInfo
    let infoNSValue = info![UIKeyboardFrameBeginUserInfoKey] as NSValue
    let kbSize = infoNSValue.CGRectValue().size
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(0.3)
    var rect : CGRect = self.view.frame
    rect.size.height += kbSize.height
    self.view.frame = rect
    UIView.commitAnimations()
}
0
fede1608

Wenn sich das Textfeld am unteren Rand des Bildschirms befinden sollte, ist die magischste Lösung die folgende Überschreibung auf Ihrem Viewcontroller:

override var inputAccessoryView: UIView? {
    return <yourTextField>
}
0

Wir können den Code für Swift 4.1 eingeben

    let keyBoardSize = 80.0

    func keyboardWillShow() {

    if view.frame.Origin.y >= 0 {
    viewMovedUp = true
     }
     else if view.frame.Origin.y < 0 {
    viewMovedUp = false
   }
  }

func keyboardWillHide() {
 if view.frame.Origin.y >= 0 {
    viewMovedUp = true
 }
 else if view.frame.Origin.y < 0 {
    viewMovedUp = false
 }

}

func textFieldDidBeginEditing(_ textField: UITextField) {
   if sender.isEqual(mailTf) {
    //move the main view, so that the keyboard does not hide it.
    if view.frame.Origin.y >= 0 {
        viewMovedUp = true
    }
  }
}

func setViewMovedUp(_ movedUp: Bool) {
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(0.3)
    // if you want to slide up the view
let rect: CGRect = view.frame
if movedUp {

    rect.Origin.y -= keyBoardSize
    rect.size.height += keyBoardSize
}
else {
    // revert back to the normal state.
    rect.Origin.y += keyBoardSize
    rect.size.height -= keyBoardSize
 }
 view.frame = rect
 UIView.commitAnimations()
}

func viewWillAppear(_ animated: Bool)  {
super.viewWillAppear(animated)

NotificationCenter.default.addObserver(self, selector:#selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(self.keyboardWillHide), name: .UIKeyboardWillHide, object: nil)
}

func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
0
Pankaj Jangid

in (BOOL) textFieldShouldBeginEditing: (UITextField *) textField

if (textField.frame.Origin.y > self.view.frame.size.height - 216)
    {
        if (screenHeight>500)
            scrollView.contentSize = CGSizeMake(0.0, scrollView.contentSize.height + 100);
        else
            scrollView.contentSize = CGSizeMake(0.0, scrollView.contentSize.height + 216);
        CGPoint scrollPoint = CGPointMake(0.0,(textField.frame.Origin.y - (self.view.frame.size.height - 216 - textField.frame.size.height - 20)));
        [scrollView setContentOffset:scrollPoint animated:YES];
    }
    [scrollView setScrollEnabled:YES];

wenn Sie Keyboard zurücktreten, müssen Sie den folgenden Code schreiben

scrollView.contentSize = CGSizeMake(0.0, 640);
CGPoint scrollPoint = CGPointMake(0.0,0.0);
[scrollView setContentOffset:scrollPoint animated:YES]; 
0
PVCS

Für Swift Entwickler mit Swift 3 ist hier das Repo https://github.com/jamesrochabrun/KeyboardWillShow

import UIKit

class ViewController: UIViewController {

    //1 Create a view that will hold your TEXTFIELD
    let textField: UITextField = {
        let tf = UITextField()
        tf.translatesAutoresizingMaskIntoConstraints = false
        tf.layer.borderColor = UIColor.darkGray.cgColor
        tf.layer.borderWidth = 3.0
        return tf
    }()
    //2 global variable that will hold the bottom constraint on changes
    var textfieldBottomAnchor: NSLayoutConstraint?

    override func viewDidLoad() {
        super.viewDidLoad()
        //3 add the view to your controller
        view.addSubview(textField)
        textField.heightAnchor.constraint(equalToConstant: 80).isActive = true
        textField.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
        textField.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        textfieldBottomAnchor = textField.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        textfieldBottomAnchor?.isActive = true

        setUpKeyBoardObservers()
    }
    //4 Use NSnotificationCenter to monitor the keyboard updates
    func setUpKeyBoardObservers() {
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    //5 toggle the bottom layout global variable based on the keyboard's height
    func handleKeyboardWillShow(notification: NSNotification) {

        let keyboardFrame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect
        if let keyboardFrame = keyboardFrame {
            textfieldBottomAnchor?.constant = -keyboardFrame.height
        }
        let keyboardDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double
        if let keyboardDuration = keyboardDuration {
            UIView.animate(withDuration: keyboardDuration, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }

    func handleKeyboardWillHide(notification: NSNotification) {

        textfieldBottomAnchor?.constant = 0
        let keyboardDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double
        if let keyboardDuration = keyboardDuration {
            UIView.animate(withDuration: keyboardDuration, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }
    //6 remove the observers
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        NotificationCenter.default.removeObserver(self)
    }
}
0
James Rochabrun

In iOS ist das Verschieben der Tastatur und das Zurücknehmen von Textfeldern in der App etwas verwirrend und Sie müssen einige Methoden für das gleiche . Implementieren. Außerdem müssen Sie das Delegieren in das Textfeld vornehmen und darauf achten jede Klasse, in der die Textfelder vorhanden sind.

Ich ziehe es vor, dieses Github-Steuerelement zu verwenden. 

IQKeyboard

In dem Wir müssen nichts tun. - Ziehen Sie einfach die Drop-Control-Taste zu Ihrem Projekt und Build. - Es wird alles für Ihre App tun.

Vielen Dank 

Vielleicht ist das nützlich.

0
Esha

Ich habe festgestellt, dass @DK_ die Lösung ist, mit der ich angefangen habe. Es wird jedoch davon ausgegangen, dass die scrollView die gesamte Ansicht abdeckt. Das war bei mir nicht der Fall. Ich wollte nur eine scrollView für den Fall, dass die Tastatur das untere Textfeld meines Anmeldebildschirms verdeckt. Daher hatte meine Inhaltsansicht dieselbe Größe wie meine Bildlaufansicht, die kleiner als die Hauptansicht war.

Landschaften waren auch nicht berücksichtigt, weshalb ich anfänglich in Schwierigkeiten geriet. Nachdem ich einige Tage damit herumgespielt habe, ist dies meine keyboardWasShown: Methode.

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    // A lot of the inspiration for this code came from http://stackoverflow.com/a/4837510/594602
    CGFloat height = 0;
    NSDictionary* info = [aNotification userInfo];

    CGRect kbFrameRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect kbBoundsRect = [self.view convertRect:kbFrameRect fromView:nil]; // Convert frame from window to view coordinates.

    CGRect scrollRect = scrollView.frame;
    CGRect intersect = CGRectIntersection(kbBoundsRect, scrollRect);

    if (!CGRectIsNull(intersect))
    {
        height = intersect.size.height;
        UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, height, 0.0);
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;
    }

    // Figure out what the view rectangle is for the scrollView
    CGPoint contentOffset = scrollView.contentOffset;
    CGRect visibleRect = CGRectOffset(scrollRect, contentOffset.x, contentOffset.y);    // I'm not 100% sure if this is needed/right. My scrollView was always at the top in testing.
    visibleRect.size.height -= height;
    CGRect activeRect = activeField.frame;

    if (!CGRectContainsRect(visibleRect, activeRect))
    {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

Ich hatte auch einige Schwierigkeiten, mit dem automatischen Layout zu arbeiten. Wenn die Layouts nicht korrekt erstellt wurden, wird der erwartete Bildlauf nicht ausgeführt. Eine Sache, die das Leben viel einfacher machte, war, alle Elemente, die gescrollt werden sollten, in einer einzigen Ansicht zu platzieren und diese als das einzige Element in der Scroll-Ansicht zu platzieren. Ich habe diese einzelne Ansicht die "Inhaltsansicht" genannt.

Ich denke, der Schlüssel war, dass die Inhaltsansicht eine festgelegte Breite und Höhe hatte. Dadurch konnte die Bildlaufansicht genau wissen, mit wie viel Inhalten sie umgehen musste. Dies geht etwas rückwärts von den üblichen Layouts. Normalerweise versuchen die Ansichten, so viel Platz wie möglich einzunehmen. Mit dem Inhalt einer Bildlaufansicht versuchen Sie, die Ansicht so weit wie möglich einzuschränken. In der Inhaltsansicht können Sie dem ein Ende setzen. Also gab ich mir eine Höhe von 248 und verwendete die Standard-Bildschirmbreite von 320 als meine Breite.

Die Layouts, die letztendlich für mich funktionierten, waren folgende:

  • Ansicht zur Superansicht scrollen: Grundsätzlich habe ich Einschränkungen oben, links und rechts angegeben.
    • Horizontal Space - View - Scroll View (0)
    • Vertical Space - View - Scroll View (0)
    • Horizontal Space - Scroll View - View (0)
  • Höhe der Bildlaufansicht: Ich habe die Bildlaufansicht auf eine konstante Höhe eingestellt. Ich weiß nicht, ob dies wirklich notwendig war, aber es hat die Grenzen der Scroll-Ansicht selbst.
    • Height - (248) - Scroll View
  • Die Inhaltsansicht zur Bildlaufansicht: Ich habe allen Seiten Konstanten zugewiesen, oben, links, unten und rechts.
    • Vertical Space - View - Scroll View (0)
    • Vertical Space - Scroll View - View (0)
    • Horizontal Space - View - Scroll View (0)
    • Horizontal Space - Scroll View - View (0)
  • Die Dimensionen der Inhaltsansicht.
    • Height - (248) - View
    • Width - (320) - View
0
Erik Allen

Sie können dieses einfache Git-Repository verwenden: https://github.com/hackiftekhar/IQKeyboardManager

Dies ist eine Bibliothek, die das Verschieben von Feldern automatisch verwaltet.

Laut ihrer Readme-Datei ist die Integration sehr einfach:

ohne dass Sie einen Code eingeben müssen und keine weiteren Einstellungen erforderlich sind. Um IQKeyboardManager verwenden zu können, müssen Sie einfach Quelldateien zu Ihrem Projekt hinzufügen.

Dies ist zwar eine sehr gute Kontrolle, in manchen Fällen führt dies jedoch zu Konflikten, wie bei den View-Controllern mit Scroll-Ansicht. Manchmal ändert sich die Inhaltsgröße. Sie können es trotzdem versuchen und es je nach Ihren Anforderungen ausprobieren. Vielleicht könnten Sie tun, was ich vermisst habe.

0
Harminder Singh

siehe UICatalogView Beispiele für iPhone live und geladen

0
Ankit Sachan

ich hatte ein Problem mit dem Zurücksetzen in die Standard-Hauptansicht, während das Textfeld geändert wurde oder dessen Inhalt bearbeitet wurde (z. B. Telefon-Textfeld und Hinzufügen von "-" - Zeichen, und Ansicht geht zurück auf Textfelder) Das Ändern von Bedingungen konstant, nicht die Frame-Größe oder Position in Benachrichtigungs-Delegaten-Funktionen, wie folgt:

P.S. Ich verwende Scrollview nicht einfach nur nach oben, aber es sollte ähnlich funktionieren

func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
    if !keyboardIsShown{
        self.infoViewTopConstraint.constant -= keyboardSize.height
        self.infoViewBottomConstraint.constant += keyboardSize.height
        self.view.setNeedsLayout()
        self.view.layoutIfNeeded()
        keyboardIsShown = true
    }
}

func keyboardWillHide(notification: NSNotification) {
if keyboardIsShown {
    self.infoViewTopConstraint.constant += keyboardSize.height
    self.infoViewBottomConstraint.constant -= keyboardSize.height
    self.view.setNeedsLayout()
    self.view.layoutIfNeeded()
    keyboardIsShown = false
}
0
Robert Juz

Diese Frage hat bereits viele Antworten, von denen einige sagten, dass sie die Scroll-Ansicht verwenden, einige sagten, dass sie eine dritte lib verwenden.

Aber für mich sollte die Ideenlösung UITableViewController mit statischen Zellen sein.

Sie trennen Ihre Benutzeroberfläche in mehrere Teile und legen diese nacheinander in die tableViewCells ein. Dann brauchen Sie sich keine Sorgen mehr um die Tastatur zu machen. TableViewController verwaltet es automatisch für Sie. 

Es kann ein wenig schwierig sein, die Auffüllung, den Rand und die Zellenhöhe zu berechnen, aber wenn Ihre Berechnungen in Ordnung sind, ist es einfach.

0
JIE WANG

Ich verwende Swift und Auto Layout (kann die vorherige Swift-Antwort jedoch nicht kommentieren); So mache ich das ohne Scrollen:

Ich gestalte mein Formular in IB mit vertikalen Einschränkungen zwischen den Feldern, um sie voneinander zu trennen. Ich füge der Containeransicht eine vertikale Einschränkung aus dem obersten Feld hinzu und erstelle einen Auslass dazu (topSpaceForFormConstraint im nachstehenden Code). Alles, was Sie brauchen, ist, diese Einschränkung zu aktualisieren, was ich in einem Animationsblock für eine Nice-Soft-Bewegung mache. Die Höhenüberprüfung ist natürlich optional. In diesem Fall musste ich sie nur für die kleinste Bildschirmgröße durchführen.

Dies kann mit einer der üblichen textFieldDidBeginEditing- oder keyboardWillShow-Methoden aufgerufen werden. 

func setFormHeight(top: CGFloat)
{
    let height = UIScreen.mainScreen().bounds.size.height

    // restore text input fields for iPhone 4/4s
    if (height < 568) {
        UIView.animateWithDuration(0.2, delay: 0.0, options: nil, animations: {
            self.topSpaceForFormConstraint.constant = top
            self.view.layoutIfNeeded()
            }, completion: nil)
    }

}
0
Anthony Scott

Ich habe diese Möglichkeit hier nicht gesehen, also füge ich sie hinzu, da ich die Methoden in den Antworten ausprobiert habe, aber Stunden später festgestellt habe, dass es eine Menge gibt. Einfacherer Weg in XCode 5 unter iOS6/7: Verwenden Sie NSLayoutConstraints.

Siehe: Autolayout-Einschränkung - Tastatur

Hier ist mein Code:

.m Datei:

// Called when the UIKeyboardWillShowNotification is sent.
- (void)keyboardWillBeShown:(NSNotification*)aNotification
{
    NSLog(@"keyboardWillBeShown:");
    [self.PhoneNumberLabelOutlet setHidden:TRUE];
    CGFloat heightOfLabel = self.PhoneNumberLabelOutlet.frame.size.height;
    for( NSLayoutConstraint* thisConstraint in self.topElementsVerticalDistanceFromTopLayoutConstraint ) {
        thisConstraint.constant -= heightOfLabel;
    }

    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGFloat oldConstant = [self.SignInYConstraint constant];
    self.SignInYConstraint.constant = oldConstant + kbSize.height;
    [self.view setNeedsUpdateConstraints];

    NSTimeInterval duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    [UIView animateWithDuration:duration animations:^{
        [self.view layoutIfNeeded];
    }];

}

.h Datei:

#import <UIKit/UIKit.h>

@interface SignInViewController : UIViewController {

    UITextField* _activeField;
}




- (void)signInCallback:(NSObject*)object;


@property (weak, nonatomic) IBOutlet UILabel *PhoneNumberLabelOutlet;

@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *ActivityIndicatorOutlet;

@property (weak, nonatomic) IBOutlet UITextField *UserIDTextfieldOutlet;

@property (weak, nonatomic) IBOutlet UITextField *PasswordTextfieldOutlet;

@property (weak, nonatomic) IBOutlet UIButton *SignInButton;

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *SignInYConstraint;

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *topElementsVerticalDistanceFromTopLayoutConstraint;

@end
0
xaphod

Swift 5

in viewDidLoad oder viewDidAppear add addKeyboardObservers -Methode.

fileprivate func addKeyboardObservers(){
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

fileprivate func removeKeyboardObservers(){
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
}


@objc fileprivate func keyboardWillHide(_ notification: Notification){
    if (window == nil) {return}
    guard let duration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double) else {return}

   scrollView.contentInset.bottom = .zero
}


@objc fileprivate func keyboardWillShow(_ notification: Notification){
    if (window == nil) {return}
    if UIApplication.shared.applicationState != .active { return }

    // keyboard height
    guard let height = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height else {return}
    // keyboard present animation duration
    guard let duration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double) else {return}

   scrollView.contentInset.bottom = height
}

vergiss nicht, Beobachter beim Deinitieren zu entfernen oder zu verschwinden

    self.removeKeyboardObservers()

ich bin ein bisschen spät dran. Sie sollten scrollView auf Ihrem viewController hinzufügen. 

Sie müssen unter 2 Methode implementieren.

TextField-Delegatmethode.

    - (void)textFieldDidBeginEditing:(UIView *)textField {
    [self scrollViewForTextField:reEnterPINTextField];
}

Rufen Sie dann die folgende Methode in Delegate auf.

 - (void)scrollViewForTextField:(UIView *)textField {
    NSInteger keyboardHeight = KEYBOARD_HEIGHT;

    if ([textField UITextField.class]) {
        keyboardHeight += ((UITextField *)textField).keyboardControl.activeField.inputAccessoryView.frame.size.height;
    } 

    CGRect screenFrame = [UIScreen mainScreen].bounds;
    CGRect aRect = (CGRect){0, 0, screenFrame.size.width, screenFrame.size.height - ([UIApplication sharedApplication].statusBarHidden ? 0 : [UIApplication sharedApplication].statusBarFrame.size.height)};
    aRect.size.height -= keyboardHeight;
    CGPoint relativeOrigin = [UIView getOriginRelativeToScreenBounds:textField];
    CGPoint bottomPointOfTextField = CGPointMake(relativeOrigin.x, relativeOrigin.y + textField.frame.size.height);

    if (!CGRectContainsPoint(aRect, bottomPointOfTextField) ) {
        CGPoint scrollPoint = CGPointMake(0.0, bottomPointOfTextField.y -aRect.size.height);
        [contentSlidingView setContentOffset:scrollPoint animated:YES];
    }
}
0
Emre Gürses

Füge meine 5 Cent hinzu :)

Ich ziehe immer vor, tableView für inputTextField oder scrollView zu verwenden. In Kombination mit Benachrichtigungen können Sie dieses Verhalten problemlos verwalten. (Hinweis: Wenn Sie statische Zellen in tableView verwenden, wird dieses Verhalten automatisch für Sie verwaltet.)

// MARK: - Notifications
fileprivate func registerNotificaitions() {
    NotificationCenter.default.addObserver(self, selector: #selector(AddRemoteControlViewController.keyboardWillAppear(_:)),
                                           name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(AddRemoteControlViewController.keyboardWillDisappear),
                                           name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

fileprivate func unregisterNotifications() {
    NotificationCenter.default.removeObserver(self)
}

@objc fileprivate func keyboardWillAppear(_ notification: Notification) {
    if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        view.layoutIfNeeded()
        UIView.animate(withDuration: 0.3, animations: {
            let heightInset = keyboardHeight - self.addDeviceButton.frame.height
            self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: heightInset, right: 0)
            self.view.layoutIfNeeded()
        }, completion: nil)
    }
}

@objc fileprivate func keyboardWillDisappear() {
    view.layoutIfNeeded()
    UIView.animate(withDuration: 0.3, animations: {
        self.tableView.contentInset = UIEdgeInsets.zero
        self.view.layoutIfNeeded()
    }, completion: nil)
}
0
gbk