Jak Mogę sprawić, że pole UITextField przesunie się w górę, gdy klawiatura jest obecna?

Z iOS SDK:

Mam UIView z UITextField S, które przywołują klawiaturę. Potrzebuję go, aby móc:

  1. Umożliwia przewijanie zawartości UIScrollView, aby zobaczyć pozostałe pola tekstowe po uruchomieniu klawiatury

  2. Automatycznie "przeskakuj" (przewijając w górę) lub skracając

Wiem, że potrzebuję UIScrollView. Próbowałem zmienić klasę mojego UIView na UIScrollView, ale nadal nie mogę przewijać pól tekstowych w górę lub w dół.

Czy potrzebuję zarówno UIView jak i UIScrollView? Czy jeden wchodzi do drugiego?

Co należy zaimplementować, aby automatycznie przewijać do aktywnego pola tekstowego?

Najlepiej jak najwięcej konfiguracji komponentów zostanie wykonane w Interface Builder. Chciałbym napisać kod tylko dla tego, czego potrzebuje.

Uwaga: UIView (lub UIScrollView), z którymi pracuję, jest przywoływany przez pasek Tabb (UITabBar), który musi działać normalnie.


Edit: I dodaję pasek przewijania tylko po pojawieniu się klawiatury. Mimo że nie jest to potrzebne, czuję, że zapewnia lepszy interfejs, ponieważ wtedy użytkownik może przewijać i zmieniać pola tekstowe, na przykład.

Mam to działa, gdzie zmieniam rozmiar klatki UIScrollView Kiedy klawiatura idzie w górę iw dół. Po prostu używam:

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

To jednak nie powoduje automatycznego "przesunięcia" lub wyśrodkowania dolnych pól tekstowych w widocznym obszarze, co naprawdę chciałbym.

Author: philfreo, 2009-07-14

30 answers

  1. Będziesz potrzebował tylko ScrollView, jeśli zawartość, którą teraz posiadasz, Nie mieści się na ekranie iPhone ' a. (Jeśli dodajesz ScrollView jako superwizor komponentów. wystarczy, że TextField przewiń w górę, gdy pojawi się klawiatura, wtedy nie jest to potrzebne.)

  2. Aby wyświetlać textfields bez ukrywania przez klawiaturę, standardowym sposobem jest przesuwanie widoku w górę/w dół z polami tekstowymi za każdym razem, gdy klawiatura jest pokazana.

Oto przykładowy kod:

#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];
}
 979
Author: RPDP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 18:21:16

Miałem również wiele problemów z UIScrollView składaniem wielu UITextFields, z których jeden lub więcej z nich zostałoby zasłoniętych przez klawiaturę podczas edycji.

Oto kilka rzeczy do rozważenia, jeśli twój UIScrollView nie jest prawidłowo przewijany.

1) Upewnij się, że contentSize jest większy niż rozmiar ramki UIScrollView. Sposobem na zrozumienie UIScrollViews jest to, że {[1] } jest jak okno podglądu zawartości zdefiniowanej w contentSize. Więc kiedy w kolejności dla UIScrollview aby przewijać w dowolnym miejscu, rozmiar zawartości musi być większy niż UIScrollView. W przeciwnym razie nie jest wymagane przewijanie, ponieważ wszystko zdefiniowane w contentSize jest już widoczne. BTW, default contentSize = CGSizeZero.

2) Teraz, gdy rozumiesz, że {[1] } jest naprawdę oknem do Twojej "zawartości", sposobem na upewnienie się, że klawiatura nie zasłania twojego UIScrollView's wyświetlania "okna" będzie zmiana rozmiaru UIScrollView tak, że gdy klawiatura jest obecna, MASZ {[1] } okno wielkości tylko oryginalnego UIScrollView frame.rozmiar.wysokość minus wysokość klawiatury. Zapewni to, że Twoje okno będzie tylko tym małym obszarem widocznym.

3) Oto haczyk: kiedy po raz pierwszy zaimplementowałem to, pomyślałem, że będę musiał uzyskać CGRect edytowanego pola tekstowego i wywołać UIScrollView's scrollRecToVisible metodę. Zaimplementowałem metodę UITextFieldDelegate {[18] } z wywołaniem metody scrollRecToVisible. To naprawdę zadziałało z dziwnym efektem ubocznym, że przewijanie przyciągnie UITextField na miejsce. Na najdłużej nie mogłem rozgryźć, co to było. Następnie skomentowałem metodę textFieldDidBeginEditing Delegate i to wszystko działa!!(???). Jak się okazało, wydaje mi się, że UIScrollView w sposób implicite przenosi aktualnie edytowany UITextField do okna podglądu implicite. Moja implementacja metody UITextFieldDelegate i późniejsze wywołanie metody scrollRecToVisible było zbędne i było przyczyną dziwnego efektu ubocznego.

Oto kroki, aby prawidłowo przewijać UITextField w UIScrollView na miejsce, gdy klawiatura pojawia się.

// 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. Zarejestruj się, aby otrzymywać powiadomienia z klawiatury na viewDidLoad
  2. Niezarejestrowanie klawiatury na viewDidUnload
  3. upewnij się, że {[30] } jest ustawione i większe niż Twoje UIScrollView na viewDidLoad
  4. Shrink the UIScrollView when the keyboard is present
  5. Przywróć UIScrollView gdy klawiatura odejdzie.
  6. użyj ivar, aby wykryć, czy klawiatura jest już wyświetlana na ekranie, ponieważ powiadomienia z klawiatury są wysyłane za każdym razem, gdy UITextField jest zakładka, nawet jeśli klawiatura jest już obecna, aby uniknąć kurczenia się UIScrollView gdy jest już skurczona

Należy pamiętać, że UIKeyboardWillShowNotification uruchomi się nawet wtedy, gdy klawiatura jest już na ekranie, gdy zakładka na innym UITextField. Zająłem się tym, używając ivar, aby uniknąć zmiany rozmiaru UIScrollView, gdy klawiatura jest już na ekranie. Nieumyślna zmiana rozmiaru UIScrollView, gdy klawiatura jest już katastrofa!

Mam nadzieję, że ten kod oszczędzi niektórym z was bólu głowy.
 437
Author: Shiun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-31 12:58:42

Najlepiej jest po prostu użyć implementacji Apple, zgodnie z docs . Jednak podany przez nich kod jest wadliwy. Zastąp część znajdującą się w keyboardWasShown: tuż pod komentarzami na:

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

Problemy z kodem Apple ' a są następujące: (1) zawsze obliczają, czy punkt znajduje się w ramce widoku, ale jest to ScrollView, więc może już się przewijał i musisz uwzględnić to przesunięcie:

origin.y -= scrollView.contentOffset.y

(2) przesuwają contentOffset o wysokość z klawiatury, ale chcemy odwrotnie (chcemy przesunąć contentOffset o wysokość widoczną na ekranie, a nie o to, co nie jest):

activeField.frame.origin.y-(aRect.size.height)
 261
Author: DK_,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-09 18:21:37

In textFieldDidBeginEditting i in textFieldDidEndEditing wywołują funkcję [self animateTextField:textField up:YES] w następujący sposób:

-(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];
}
Mam nadzieję, że ten kod ci pomoże.

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)
    }
 238
Author: sumanthkodi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-04 15:21:45

Wystarczy użyć pola tekstowego:

1a) za pomocą Interface Builder: Zaznacz wszystkie pola tekstowe = > Edycja = > osadzanie w = > Przewijanie

1b) ręczne osadzanie pól tekstowych w UIScrollView o nazwie scrollView

2) Set UITextFieldDelegate

3) Ustaw każdy textField.delegate = self; (lub wykonaj połączenia w Interface Builder)

4) Kopiuj / Wklej:

- (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
Author: DAS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-01 14:53:19

Dla uniwersalnego rozwiązania oto moje podejście do implementacji IQKeyboardManager.

Tutaj wpisz opis obrazka

Krok 1: - dodałem globalne powiadomienia o UITextField, UITextView, i UIKeyboard w klasie singleton. Nazywam to IQKeyboardManager .

Krok 2: - jeśli znaleziono UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotification lub UITextViewTextDidBeginEditingNotification powiadomień, staram się uzyskać instancję topMostViewController z hierarchii UIWindow.rootViewController. Aby prawidłowo odkryć UITextField/UITextView na nim topMostViewController.view ramka musi być / align = "left" /

Krok 3: - obliczyłem oczekiwaną odległość ruchu topMostViewController.view w odniesieniu do pierwszej odpowiedzi UITextField/UITextView.

Krok 4: - przesunąłem się topMostViewController.view.frame w górę/w dół zgodnie z oczekiwaną odległością ruchu.

Krok 5: - jeśli znaleziono UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification lub UITextViewTextDidEndEditingNotification powiadomienie, ponownie staram się uzyskać instancję topMostViewController z hierarchii UIWindow.rootViewController.

Krok 6: - obliczyłem odległość {[10] } którą trzeba przywrócić do oryginału pozycji.

Krok 7: - przywróciłem topMostViewController.view.frame w dół zgodnie z zakłóconą odległością.

Krok 8:- utworzyłem instancję klasy singleton iqkeyboardmanager podczas ładowania aplikacji, więc każdy UITextField/UITextView w aplikacji dostosuje się automatycznie w zależności od oczekiwanej odległości ruchu.

To wszystko IQKeyboardManager zrób dla Ciebie z Brak linii kodu naprawdę!! wystarczy przeciągnąć i upuścić powiązany plik źródłowy do projektu. IQKeyboardManager obsługuje również orientację urządzenia , Automatyczne zarządzanie UIToolbar, KeybkeyboardDistanceFromTextField i znacznie więcej niż myślisz.

 106
Author: Mohd Iftekhar Qurashi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-18 16:24:01

Ułożyłem uniwersalny, drop-in UIScrollView, UITableView a nawet UICollectionView podklasa, która zajmuje się przesuwaniem wszystkich pól tekstowych wewnątrz niej poza klawiaturę.

Gdy klawiatura ma się pojawić, podklasa znajdzie podkategorię, która ma być edytowana, i dostosuje jej przesunięcie ramki i zawartości, aby upewnić się, że widok jest widoczny, z animacją dopasowaną do wyskakującego okienka klawiatury. Kiedy klawiatura znika, przywraca swój poprzedni rozmiar.

Powinno działać z zasadniczo dowolna konfiguracja, albo interfejs oparty na UITableView, albo jeden składający się z widoków umieszczanych ręcznie.

Oto: rozwiązanie do przenoszenia pól tekstowych poza klawiaturę

 99
Author: Michael Tyson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-16 07:06:04

Dla Programistów Swift :

To zrobi wszystko za ciebie, po prostu umieść je w klasie kontrolera widoku i zaimplementuj UITextFieldDelegate do kontrolera widoku i ustaw delegata pola tekstowego na self

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

Zaimplementuj metody wywołania zwrotnego delegata:

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()
}
 84
Author: Satnam Sync,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-24 09:07:45

Istnieje już wiele odpowiedzi, ale nadal żadne z powyższych rozwiązań nie miało wszystkich fantazyjnych elementów pozycjonowania wymaganych do "doskonałej" animacji wolnej od błędów, kompatybilnej Wstecz i wolnej od migotania. (błąd podczas animowania klatek / granic i contentOffset razem, różne orientacje interfejsu, dzielona klawiatura iPada, ...)
Pozwól, że podzielę się moim rozwiązaniem:
(zakładając, że ustawiłeś UIKeyboardWill(Show|Hide)Notification)

// 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];
}
 62
Author: Martin Ullrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-24 09:40:19

Shiun powiedział: "jak się okazało, uważam, że uiscrollview faktycznie domyślnie przenosi aktualnie edytowane pole UITextField do okna podglądu Domyślnie" to wydaje się być prawdą dla iOS 3.1.3, ale nie 3.2, 4.0 lub 4.1. Musiałem dodać jawny scrollRectToVisible, aby UITextField był widoczny na iOS > = 3.2.

 60
Author: cbranch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-17 10:45:04

Ten dokument zawiera szczegóły rozwiązania tego problemu. Spójrz na kod źródłowy w sekcji "Przenoszenie zawartości znajdującej się pod klawiaturą". To dość proste.

EDIT: zauważyłem małą usterkę w przykładzie. Prawdopodobnie będziesz chciał słuchać UIKeyboardWillHideNotification zamiast UIKeyboardDidHideNotification. W przeciwnym razie widok przewijania za klawiaturą zostanie przycięty na czas trwania animacji zamykania klawiatury.

 44
Author: Mihai Damian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 05:58:49

Jedną rzeczą do rozważenia jest to, czy kiedykolwiek chcesz użyć UITextField na własną rękę. Nie spotkałem się z żadnymi dobrze zaprojektowanymi aplikacjami na iPhone ' a, które faktycznie używają UITextFields poza UITableViewCells.

To będzie jakaś dodatkowa praca, ale polecam zaimplementować wszystkie widoki wprowadzania danych a widoki tabeli. Dodaj UITextView do swojego UITableViewCells.

 43
Author: Jonathan Sterling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 05:59:29

Najprostsze rozwiązanie znalezione

- (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];
}
 31
Author: Xar E Ahmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-25 11:10:22

Mała poprawka, która działa dla wielu UITextFields

#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]; 
}
 30
Author: tt.Kilew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 11:18:14

Kod RPDP z powodzeniem przesuwa pole tekstowe poza klawiaturę. Ale po przewinięciu do góry po użyciu i odrzuceniu klawiatury, Góra została przewinięta w górę z widoku. Dotyczy to symulatora i urządzenia. Aby odczytać zawartość u góry tego widoku, należy przeładować widok.

Czy jego następujący kod nie powinien przywrócić widoku?
else
{
    // revert back to the normal state.
    rect.origin.y += kOFFSET_FOR_KEYBOARD;
    rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
 27
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-05 18:27:10

Nie jestem pewien, czy przesunięcie widoku w górę jest właściwym podejściem, zrobiłem to w inny sposób, zmieniając rozmiar UIScrollView. Wyjaśniłem to szczegółowo w małym artykule

 22
Author: Jose Muanis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-24 10:25:47

Aby przywrócić oryginalny stan widoku, dodaj:

-(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];
    }
}
 20
Author: Nicolas Marchand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 06:06:56

Jest tyle rozwiązań, ale spędziłem kilka godzin zanim zacznie działać. Więc umieszczam ten kod tutaj (wystarczy wkleić do projektu, żadnych modyfikacji nie trzeba):

@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. s: mam nadzieję, że kod pomoże komuś szybko osiągnąć pożądany efekt. (Xcode 4.5)

 19
Author: HotJard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-12 09:14:14

Spróbuj tej krótkiej sztuczki...

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

Happy coding :)....

 18
Author: Sourabh Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-28 07:12:24

@ user271753

Aby wrócić do oryginału dodaj:

-(BOOL)textFieldShouldReturn:(UITextField *)textField{
   [textField resignFirstResponder];
   [self setViewMovedUp:NO];
   return YES;
}
 17
Author: user436179,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-02 12:06:19

Nie wymaga widoku przewijania, aby móc przesunąć ramkę widoku. Możesz zmienić ramkę widoku viewcontroller's tak, aby cały widok poruszał się w górę na tyle, aby umieścić pole tekstowe firstresponder nad klawiaturą. Kiedy napotkałem ten problem, stworzyłem podklasę UIViewController, która robi to. Obserwuje dla klawiatury pojawi się powiadomienie i znajduje subview first responder i (w razie potrzeby) animuje główny widok w górę na tyle, aby pierwszy responder był powyżej klawiatura. Gdy klawiatura się ukryje, animuje widok z powrotem w miejscu, w którym była.

Aby użyć tej podklasy, Zmień swój niestandardowy kontroler widoku na podklasęGMKeyboardVC i dziedziczy tę funkcję (upewnij się tylko, że zaimplementowałeś viewWillAppear i viewWillDisappear muszą wywołać super). Klasa jest na github .

 15
Author: progrmr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 06:01:01

Zgodnie z docs, począwszy od iOS 3.0, klasa UITableViewController automatycznie zmienia rozmiar i zmienia pozycję widoku tabeli, gdy istnieje edycja pól tekstowych w wierszu. Myślę, że nie wystarczy umieścić pole tekstowe wewnątrz UITableViewCell, Jak niektórzy wskazywali.

From the docs :

Kontroler widoku tabeli obsługuje wbudowaną edycję wierszy widoku tabeli; jeśli na przykład wiersze mają osadzone pola tekstowe w trybie edycji, to przewija edytowany wiersz nad wirtualnym klawiatura, która jest wyświetlane.

 12
Author: Dheeraj V.S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-04 02:57:16

Oto rozwiązanie hack wymyśliłem dla konkretnego układu. Rozwiązanie to jest podobne do rozwiązania Matta Gallaghera, w którym przewija się sekcję w widoku. Wciąż jestem nowy w rozwoju iPhone ' a i nie jestem zaznajomiony z tym, jak działają układy. Tak więc, ten hack.

Moja implementacja musiała obsługiwać przewijanie po kliknięciu w pole, a także przewijanie po wybraniu przez użytkownika opcji next na klawiaturze.

Miałem UIView o wzroście 775. Sterowanie jest rozłożone w zasadzie w grupach po 3 na dużej przestrzeni. Skończyło się na następującym układzie IB.
UIView -> UIScrollView -> [UI Components]

Here comes the hack

Ustawiłem wysokość UIScrollView na 500 jednostek większe niż rzeczywisty układ (1250). Następnie utworzyłem tablicę z bezwzględnymi pozycjami, do których muszę przewijać, oraz prostą funkcję, aby uzyskać je na podstawie numeru znacznika IB.

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

Teraz wystarczy użyć następujących dwóch linii kodu w textFieldDidBeginEditing i textFieldShouldReturn (ta ostatnia, jeśli tworzy kolejne pole nawigacji)

CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
[self.scrollView setContentOffset:point animated:YES] ;
Przykład.
- (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 ;
}

Ta metoda nie "przewija się do tyłu", jak robią to Inne metody. Nie było to wymagane. Ponownie było to dla dość "wysokiego" UIView, a ja nie miałem dni, aby nauczyć się wewnętrznych silników układu.

 11
Author: Steve McFarlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-28 22:17:38

Tutaj znalazłem najprostsze rozwiązanie do obsługi klawiatury.

Wystarczy skopiować i wkleić poniżej przykładowy kod i zmienić pole tekstowe lub dowolny widok, który chcesz przenieść w górę.

Krok-1

Po prostu skopiuj-wklej poniżej dwie metody w kontrolerze

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

Krok-2

Zarejestruj i Wyrejestruj powiadomienia klawiatury w viewWillAppear oraz viewwilldisappear metody odpowiednio.

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

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

Krok-3

Nadchodzi część duszy, wystarczy zastąpić pole tekstowe i zmienić wysokość jak bardzo chcesz przenieść do góry.

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

Odniesienie : dobrze., Proszę docenić tego gościa., Kto udostępnił ten piękny wycinek kodu, czyste rozwiązanie.

Mam nadzieję, że to będzie gburowaty pomocny ktoś tam.

 11
Author: swiftBoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-19 17:45:32

Szukałem dobrego samouczka dla początkujących na ten temat, znalazłem najlepszy samouczek tutaj .

W przykładzie MIScrollView.h na dole tutoriala należy umieścić spację na

@property (nonatomic, retain) id backgroundTapDelegate;
Jak widzisz.
 9
Author: savagenoob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-02 20:42:17

Użyj tej strony trzeciej nie musisz pisać nawet jednej linii

Https://github.com/hackiftekhar/IQKeyboardManager

Pobierz projekt i przeciągnij i upuść IQKeyboardManager w swoim projekcie. Jeśli znajdziesz jakiś problem, przeczytaj dokument README.

Chłopaki naprawdę jej usunąć ból głowy do zarządzania klawiatury ..

Dzięki i powodzenia!

 9
Author: Arvind Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-12 09:43:07

Gdy UITextField znajduje się w UITableViewCell przewijanie powinno być ustawione automatycznie.

Jeśli tak nie jest, to prawdopodobnie z powodu nieprawidłowego kodu/konfiguracji tableview.

Na przykład, gdy przeładowałem mój długi stół z jednym UITextField na dole w następujący sposób,

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

Potem moje pole tekstowe na dole zostało zasłonięte przez klawiaturę, która pojawiła się, gdy kliknąłem w pole tekstowe.

Aby to naprawić musiałem to zrobić -

-(void) viewWillAppear:(BOOL)animated
{
    //add the following line to fix issue
    [super viewWillAppear:animated];
    [self.tableview reloadData];
}
 9
Author: lakersgonna3peat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 06:07:49

Swift 4 .

Możesz Łatwo Poruszać Się W Górę Iw Dół UITextField Lub UIView Z UIKeyBoard Z Animation Tutaj wpisz opis obrazka

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
    }

}
 9
Author: ZAFAR007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 10:37:37

Uwaga : ta odpowiedź zakłada, że pole tekstowe znajduje się w widoku przewijania.

Wolę radzić sobie z tym za pomocą scrollContentInset i scrollContentOffset zamiast mieszać z ramkami mojego widoku.

Najpierw posłuchajmy powiadomień klawiatury

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

Następnym krokiem jest zachowanie właściwości, która reprezentuje bieżącą osobę odpowiedzialną (UITextField/ UITextView, która obecnie posiada klawiaturę).

Używamy metod delegata do Ustawienia tej właściwości. Jeśli jesteś używając innego komponentu, będziesz potrzebował czegoś podobnego.

Zauważ, że dla textfield ustawiliśmy go w didBeginEditing, a dla textView w shouldBeginEditing. Dzieje się tak dlatego, że textViewDidBeginEditing jest wywoływany po UIKeyboardWillShowNotification z jakiegoś powodu.

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

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

Wreszcie, oto Magia

- (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
Author: Juraj Petrik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 20:06:33

Jest to rozwiązanie za pomocą 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
Author: Homam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-06 05:08:32