it-swarm.com.de

Wie scrollen Sie nach oben, wenn die Tastatur angezeigt wird?

Ich weiß, dass diese Frage immer wieder gestellt wurde, aber für mich scheint nichts zu funktionieren. Die meisten Lösungen sind ziemlich veraltet und der Rest ist unglaublich große Codeblöcke, die zehnmal größer sind als die eigentliche Codierung der Projekte. Ich habe ein paar UITextFields, die vertikal aufgereiht sind, aber wenn die Tastatur gestartet wird, um eines zu bearbeiten, wird das Textfeld verdeckt. Ich habe mich gefragt, ob es einen einfachen Anfänger gibt, um die Ansicht nach oben und dann nach unten zu scrollen, wenn die Bearbeitung beginnt und endet.

Vielen Dank.

37
Henry F

Ich habe Lösungen entwickelt, die mit Scroll- und Nicht-Scroll-Ansichten arbeiten, die Tastaturbenachrichtigung verwenden und den aktuellen Ersthelfer erkennen. Manchmal verwende ich jedoch diese triviale Lösung: Die einfache Möglichkeit besteht darin, die öffnende Tastatur über die textViewDidBeginEditing:-Methode des Textfeld-Delegierten zu erkennen und um die gesamte Ansicht nach oben zu verschieben. Der einfachste Weg, dies zu tun, besteht darin, etwas in der Richtung des Änderns von self.view.bounds.Origin.y in -100 (oder was auch immer) zu ändern. Verwenden Sie die entsprechende textViewShouldEndEditing:-Methode, um das Gegenteil festzulegen, in diesem Fall 100. Das Ändern von bounds ist eine relative Prozedur. Nach dem Ändern wird der Rahmen verschoben, aber der Ursprungsrahmen ist immer noch Null.

29
Peter DeWeese

Seit ich es gefunden habe, verwende ich TPKeyboardAvoiding - https://github.com/michaeltyson/TPKeyboardAvoiding .

Es funktioniert super und ist sehr einfach einzurichten:

  • Fügen Sie eine UIScrollView zum Xib Ihres View-Controllers hinzu
  • Setzen Sie die Klasse der Bildlaufansicht auf TPKeyboardAvoidingScrollView (noch im Xib über den Identitätsinspektor).
  • Platzieren Sie alle Steuerelemente in dieser Bildlaufansicht

Sie können es auch programmgesteuert erstellen, wenn Sie möchten. 


Es gibt eine Klasse für dasselbe Bedürfnis in einer UITableViewController; es wird nur benötigt, wenn Sie eine Version von iOS unter 4.3 unterstützen.

25
Guillaume

@BenLu und andere Benutzer, die mit dem Problem der Funktion konfrontiert sind, werden aus folgenden Gründen nie aufgerufen: Da die Delegate Inbuild-Funktion bydefaults void anstelle von BOOL zurückgibt, sollte dies folgendermaßen sein:

 -(void)textFieldDidBeginEditing:(UITextField *)textField
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.35f];
    CGRect frame = self.view.frame;
    frame.Origin.y = -100;
    [self.view setFrame:frame];
    [UIView commitAnimations];
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.35f];
    CGRect frame = self.view.frame;
    frame.Origin.y = 100;
    [self.view setFrame:frame];
    [UIView commitAnimations];
}

Ich verbrachte einige Zeit mit diesem Problem und sammelte Stückcode, um eine endgültige Lösung zu erstellen. Mein Problem war mit dem Scrollen von UITableView und dem Öffnen/Schließen der Tastatur verbunden.

Sie benötigen zwei Teilmethoden in Ihrer Zellklasse:

    void EditingBegin(UITextField sender)
    {
        // Height of tallest cell, you can ignore this!
        float tableMargin = 70.0f;
        float tableHeight = _tableView.Frame.Size.Height;
        float keyBoardHeight = KeyboardHeight();

        NSIndexPath[] paths = this._tableView.IndexPathsForVisibleRows;
        RectangleF rectLast = this._tableView.RectForSection(paths[paths.Length - 1].Section);
        RectangleF rectFirst = this._tableView.RectForSection(paths[0].Section);
        float lastCellY = rectLast.Y - rectFirst.Y;
        if (lastCellY > tableHeight - keyBoardHeight)
        {
            float diff = lastCellY - (tableHeight - tableMargin - keyBoardHeight);
            this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, diff, 0.0f);
        }

        float cellPosition = this._tableView.RectForSection(this._section).Y;
        if (cellPosition > tableHeight - keyBoardHeight)
        {
            if (this._tableView.ContentInset.Bottom == 0.0f)
            {
                float diff = cellPosition - (tableHeight - tableMargin - keyBoardHeight);
                this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, diff, 0.0f);
            }
            else
            {
                this._tableView.ScrollToRow(NSIndexPath.FromItemSection(0, this._section), UITableViewScrollPosition.Middle, true);
            }
        }
    }

    partial void EditingEnd(UITextField sender)
    {
        UIView.BeginAnimations(null);
        UIView.SetAnimationDuration(0.3f);
        this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, 0.0f, 0.0f);
        UIView.CommitAnimations();
    }

und dann in Ihrer View Controller-Klasse:

    public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration)
    {
        base.WillAnimateRotation(toInterfaceOrientation, duration);

        float bottom = this.TableView.ContentInset.Bottom;
        if (bottom > 0.0f)
        {
            if (toInterfaceOrientation == UIInterfaceOrientation.Portrait || toInterfaceOrientation == UIInterfaceOrientation.PortraitUpsideDown)
            {
                bottom = bottom * UIScreen.MainScreen.Bounds.Width / UIScreen.MainScreen.Bounds.Height;
            }
            else
            {
                bottom = bottom * UIScreen.MainScreen.Bounds.Height / UIScreen.MainScreen.Bounds.Width;
            }

            UIEdgeInsets insets = this.TableView.ContentInset;
            this.TableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, bottom, 0.0f);
        }
    }  
1
U. Ali

Wenn Sie eine UITableView oder eine UIScrollView haben, sollten Sie die Werte für contentOffset ändern, anstatt die frame zu ändern. 

An Peter's Answer zu arbeiten, diese Methode zu Ihrer Klasse hinzuzufügen, funktioniert gut:

- (void)textViewDidBeginEditing:(UITextField *)textField {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.35f];
    CGPoint offset = self.tableView.contentOffset;
    offset.y += 200; // You can change this, but 200 doesn't create any problems
    [self.tableView setContentOffset:offset];
    [UIView commitAnimations];
}

Das ist es, keine Notwendigkeit, die textViewDidEndEditing-Methode hinzuzufügen.


Ich sollte das nicht sagen müssen, aber damit dies funktioniert, muss Ihre UITextField oder UITextViewein Delegat Ihres Controllers sein.

0
Sheharyar

Beginnend mit Peters Antwort habe ich in Swift 3.0 unter iOS 10.1 den folgenden Ansatz entwickelt. Ich mache dies für ein textView, also habe ich die UITextViewDelegate-Funktionen textViewDidBeginEditing und textViewDidEndEditing implementiert, wo ich die Grenzen der Ansicht anpasse. Wie Sie sehen, habe ich den Origin Y-Wert auf eine kleine positive Zahl gesetzt, um nach oben zu scrollen und dann wieder auf 0 zu kehren, um zur ursprünglichen Position zurückzukehren. 

Hier ist der relevante Code von meinem ViewController. Sie müssen nicht animieren, aber es fügt eine nette Note hinzu. 

func textViewDidBeginEditing(_ textView: UITextView)
{
    if UIScreen.main.bounds.height < 568 { 
        UIView.animate(withDuration: 0.75, animations: {
            self.view.bounds.Origin.y = 60
        })
    }
}

func textViewDidEndEditing(_ textView: UITextView)
{
    if UIScreen.main.bounds.height < 568 {
        UIView.animate(withDuration: 0.75, animations: {
            self.view.bounds.Origin.y = 0
        })
    }
}
0
Mario Hendricks