Как я могу заставить UITextField двигаться вверх при наличии клавиатуры?

С iOS SDK:

У меня есть UIView с UITextField с, которые вызывают клавиатуру. Мне нужно, чтобы иметь возможность:

  1. Разрешить прокрутку содержимого UIScrollView, чтобы увидеть другие текстовые поля после запуска клавиатуры

  2. Автоматически «прыгать» (путем прокрутки вверх) или сокращения

Я знаю, что мне нужно UIScrollView. Я попытался изменить класс моего UIView на UIScrollView, но я все еще не могу прокрутить текстовые поля вверх или вниз.

Нужны ли мне как UIView, так и UIScrollView? Один входит в другой?

Что необходимо реализовать для автоматической прокрутки к активному текстовому полю?

В идеале, максимально возможная настройка компонентов будет выполнена в Интерфейсном Разработчике. Я хотел бы написать код только для того, что нужно.

Примечание: UIView (или UIScrollView), с которым я работаю, вызывается панелью вкладок (UITabBar), которая должна функционировать как обычно.


Редактировать: Я добавляю полосу прокрутки только для того, когда клавиатура появляется. Хотя это и не нужно, но мне кажется, что он обеспечивает лучший интерфейс, потому что тогда пользователь может, например, прокручивать и изменять текстовые поля.

У меня это работает, когда я меняю размер кадра UIScrollView, когда клавиатура поднимается и опускается. Я просто использую:

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

Однако, это не автоматически «двигает вверх» или центрирует нижние текстовые поля в видимой области, что мне бы очень хотелось.

вопрос задан 14.07.2009
philfreo
25863 репутация

90 ответов


  • 978 рейтинг
    1. Вам понадобится только ScrollView, если содержимое, которое у вас сейчас есть, не помещается на экране iPhone. (Если вы добавляете ScrollView в качестве суперпредставления компонентов. просто чтобы сделать TextField прокруткой вверх, когда клавиатура появляется, тогда это не нужно. )

    2. Для отображения textfields, не будучи скрытым клавиатурой, стандартным способом является перемещение вверх / вниз по представлению, имеющему текстовые поля, всякий раз, когда отображается клавиатура.

    Вот пример кода:

    #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];
    }
    
    ответ дан RPDP, с репутацией 1408, 14.07.2009
  • 437 рейтинг

    У меня также было много проблем с композицией UIScrollView, кратной UITextFields, из которых одна или несколько из них были бы скрыты клавиатурой при редактировании.

    Вот некоторые вещи, которые следует учитывать, если ваш UIScrollView неправильно прокручивается.

    1) Убедитесь, что ваш размер содержимого больше размера кадра UIScrollView. Способ понять UIScrollViews состоит в том, что UIScrollView подобен окну просмотра контента, определенного в contentSize. Таким образом, когда для прокрутки UIScrollview в любом месте, contentSize должен быть больше, чем UIScrollView. Иначе, прокрутка не требуется, так как все, что определено в contentSize, уже видно. Кстати, contentSize по умолчанию = CGSizeZero.

    2) Теперь, когда вы понимаете, что UIScrollView действительно является окном в вашем «контенте», способ гарантировать, что клавиатура не заслоняет ваше «окно» просмотра UIScrollView's, состоит в изменении размера UIScrollView так, чтобы при наличии клавиатуры, у вас есть окно UIScrollView размером с оригинальную рамку UIScrollView. размер. высота минус высота клавиатуры. Это гарантирует, что ваше окно будет только этой маленькой видимой областью.

    3) Вот подвох: когда я впервые реализовал это, я подумал, что мне нужно получить CGRect отредактированного текстового поля и вызвать метод UIScrollView's scrollRecToVisible. Я реализовал метод UITextFieldDelegate textFieldDidBeginEditing с вызовом метода scrollRecToVisible. Это на самом деле работало со странным побочным эффектом, что прокрутка привела бы к UITextField в нужное положение. Долгое время я не мог понять, что это было. Затем я прокомментировал метод делегата textFieldDidBeginEditing, и все это работает! ! (? ? ? ). Как выяснилось, я считаю, что UIScrollView неявно приводит неявно отредактированный в настоящее время UITextField в видимое окно. Моя реализация метода UITextFieldDelegate и последующий вызов scrollRecToVisible были излишними и стали причиной странного побочного эффекта.

    Итак, вот шаги для правильной прокрутки UITextField в UIScrollView на месте, когда появляется клавиатура.

    // 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. Регистрация для уведомлений клавиатуры на viewDidLoad
    2. Отменить регистрацию для клавиатурных сообщений на viewDidUnload
    3. Убедитесь, что contentSize установлен и больше, чем ваш UIScrollView на viewDidLoad
    4. Сократите до UIScrollView при наличии клавиатуры
    5. Верните назад UIScrollView, когда клавиатура исчезнет.
    6. Используйте ивар, чтобы определить, отображается ли уже клавиатура на экране, так как уведомления клавиатуры отправляются каждый раз, когда вкладка UITextField выполняется, даже если клавиатура уже присутствует, чтобы избежать 3230269583 сокращения UIScrollView, когда оно уже уменьшилось

    Следует отметить, что UIKeyboardWillShowNotification будет срабатывать, даже если клавиатура уже находится на экране, когда вы нажимаете на другую UITextField. Я позаботился об этом, используя ivar, чтобы избежать изменения размера UIScrollView, когда клавиатура уже на экране. Случайное изменение размера UIScrollView, когда клавиатура уже есть, будет катастрофическим!

    Надеюсь, этот код избавит некоторых из вас от головной боли.

    ответ дан Shiun, с репутацией 2479, 24.04.2010
  • 261 рейтинг

    На самом деле лучше всего использовать реализацию Apple, как это предусмотрено в документах . Однако код, который они предоставляют, неисправен. Замените часть, найденную в keyboardWasShown: чуть ниже комментариев, следующим:

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

    Проблемы с кодом Apple следующие: (1) Они всегда вычисляют, находится ли точка в рамке вида, но это ScrollView, поэтому она, возможно, уже прокрутилась, и вам необходимо учесть это смещение:

    origin.y -= scrollView.contentOffset.y
    

    (2) Они сдвигают contentOffset на высоту клавиатуры, но мы хотим наоборот (мы хотим сместить contentOffset на высоту, которая видна на экране, а не то, что нет):

    activeField.frame.origin.y-(aRect.size.height)
    
    ответ дан DK_, с репутацией 2385, 29.01.2011
  • 238 рейтинг

    В textFieldDidBeginEditting и textFieldDidEndEditing вызовите функцию [self animateTextField:textField up:YES] следующим образом:

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

    Я надеюсь, что этот код поможет вам.

    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)
        }
    
    ответ дан sumanthkodi, с репутацией 181, 2.08.2011
  • 133 рейтинг

    Просто используя TextFields:

    1a) Использование Interface Builder: выбрать все текстовые поля = & gt; Редактировать = & gt; Вставить в = & gt; ScrollView

    1b) Ввести TextFields вручную в UIScrollView с именем scrollView

    2) Набор UITextFieldDelegate

    3) Установите каждый textField.delegate = self; (или выполните соединения в Interface Builder)

    4) Копия / вставка:

    - (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];
    }
    
    ответ дан DAS, с репутацией 1565, 1.12.2012
  • 106 рейтинг

    Для универсального решения . Вот мой подход к реализации IQKeyboardManager .

    enter image description here

    Шаг 1: - I Добавлены глобальные уведомления UITextField, UITextView и UIKeyboard в классе синглтона. Я называю это IQKeyboardManager .

    Шаг 2: - Если обнаружены уведомления UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotification или UITextViewTextDidBeginEditingNotification, я пытаюсь получить экземпляр topMostViewController из иерархии UIWindow.rootViewController. Для того, чтобы правильно открыть UITextField/UITextView на нем, необходимо отрегулировать кадр topMostViewController.view.

    Шаг 3: - Я вычислил ожидаемое расстояние перемещения topMostViewController.view относительно первого ответившего UITextField/UITextView.

    Шаг 4: - Я переместился на topMostViewController.view.frame вверх / вниз в соответствии с ожидаемым расстоянием перемещения.

    Шаг 5: - Если найдено уведомление UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification или UITextViewTextDidEndEditingNotification, я снова пытаюсь получить экземпляр topMostViewController из иерархии UIWindow.rootViewController.

    Шаг 6: - Я рассчитал нарушенное расстояние topMostViewController.view, которое необходимо восстановить в исходное положение.

    Шаг 7: - Я восстановил topMostViewController.view.frame в соответствии с нарушенным расстоянием.

    Шаг 8: - Я создал экземпляр синглтона IQKeyboardManager при загрузке приложения, поэтому каждый UITextField/UITextView в приложении будет автоматически корректироваться в соответствии с ожидаемым расстоянием перемещения.

    Вот и все IQKeyboardManager для вас с НЕТ ЛИНИИ КОДА действительно! ! нужно только перетащить связанный исходный файл в проект. IQKeyboardManager также поддерживает Ориентацию устройства , Автоматическое управление UIToolbar , KeybkeyboardDistanceFromTextField и намного больше, чем вы думаете.

    ответ дан Mohd Iftekhar Qurashi, с репутацией 2126, 17.07.2013
  • 99 рейтинг

    Я собрал универсальный вставной подкласс UIScrollView, UITableView и даже UICollectionView, который заботится о перемещении всех текстовых полей в нем из клавиатуры.

    Когда клавиатура должна появиться, подкласс найдет подпредставление, которое должно быть отредактировано, и отрегулирует его фрейм и смещение содержимого, чтобы убедиться, что представление является видимым, с анимацией, соответствующей всплывающей клавиатуре. Когда клавиатура исчезает, она восстанавливает свой прежний размер.

    Он должен работать практически с любой настройкой, либо с интерфейсом на основе UITableView, либо с интерфейсом, состоящим из представлений, размещенных вручную.

    Вот это решение для перемещения текстовых полей с клавиатуры на место:

    ответ дан Michael Tyson, с репутацией 1280, 12.04.2011
  • 84 рейтинг

    Для Swift Программисты:

    Это все сделает за вас, просто поместите их в свой класс контроллера представления и внедрите UITextFieldDelegate в свой контроллер представления & amp; установите делегата textField на self

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

    Реализуйте методы обратного вызова делегата:

    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()
    }
    
    ответ дан Satnam Sync, с репутацией 1180, 30.04.2015
  • 62 рейтинг

    Уже есть много ответов, но все же ни одно из вышеприведенных решений не имело всех причудливых средств позиционирования, необходимых для «идеальной» безошибочной, обратно совместимой и не мерцающей анимации. (ошибка при анимации frame / bounds и contentOffset вместе, различные ориентации интерфейса, разделенная клавиатура iPad,. , , )
    Позвольте мне поделиться своим решением:
    (при условии, что вы настроили 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];
    }
    
    ответ дан Martin Ullrich, с репутацией 38158, 1.03.2013
  • 60 рейтинг

    Шиун сказал: «Как оказалось, я полагаю, что UIScrollView фактически неявно переводит в настоящий момент отредактированный UITextField в видимое окно». Это похоже на правду для iOS 3. 1. 3, но не 3. 2, 4. 0 или 4. 1. Мне пришлось добавить явный scrollRectToVisible, чтобы сделать UITextField видимым на iOS & gt; = 3. 2.

    ответ дан cbranch, с репутацией 3843, 6.11.2010
  • 44 рейтинг

    Этот документ подробно описывает решение этой проблемы. Посмотрите на исходный код в разделе «Перемещение содержимого, расположенного под клавиатурой». Это довольно просто.

    РЕДАКТИРОВАТЬ: заметил, что в примере есть крошечный глюк. Вы, вероятно, захотите послушать UIKeyboardWillHideNotification вместо UIKeyboardDidHideNotification. В противном случае представление прокрутки позади клавиатуры будет обрезано на время анимации закрытия клавиатуры.

    ответ дан Mihai Damian, с репутацией 5931, 28.10.2010
  • 43 рейтинг

    Одна вещь, чтобы рассмотреть, хотите ли вы когда-либо использовать UITextField самостоятельно. Я не сталкивался ни с какими хорошо разработанными приложениями для iPhone, которые на самом деле используют UITextFields за пределами UITableViewCells.

    Это будет дополнительная работа, но я рекомендую вам реализовать все представления ввода данных в виде таблицы. Добавьте UITextView к вашему UITableViewCells.

    ответ дан Jonathan Sterling, с репутацией 14452, 20.07.2009
  • 31 рейтинг

    Самое простое решение найдено

    - (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];
    }
    
    ответ дан Xar E Ahmer, с репутацией 21729, 25.10.2014
  • 30 рейтинг

    Небольшое исправление, которое работает для многих 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]; 
    }
    
    ответ дан tt.Kilew, с репутацией 4388, 11.02.2010
  • 27 рейтинг

    Код RPDP успешно перемещает текстовое поле с клавиатуры. Но когда вы прокручиваете до верха после использования и отклонения клавиатуры, верхняя часть прокручивается вверх из вида. Это верно для симулятора и устройства. Чтобы прочитать содержимое в верхней части этого представления, необходимо перезагрузить представление.

    Разве его следующий код не должен вернуть представление вниз?

    else
    {
        // revert back to the normal state.
        rect.origin.y += kOFFSET_FOR_KEYBOARD;
        rect.size.height -= kOFFSET_FOR_KEYBOARD;
    }
    
    ответ дан Steve, с репутацией 509, 5.02.2010
  • 22 рейтинг

    Я не уверен, что перемещение представления вверх является правильным подходом, я сделал это другим способом, изменив размер UIScrollView. Я объяснил это в деталях на маленькой статье

    ответ дан Jose Muanis, с репутацией 517, 10.01.2010
  • 20 рейтинг

    Чтобы вернуть исходное состояние просмотра, добавьте:

    -(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];
        }
    }
    
    ответ дан Nicolas Marchand, с репутацией 41, 10.02.2010
  • 19 рейтинг

    Есть так много решений, но я потратил несколько часов, прежде чем он начнет работать. Итак, я поместил этот код здесь (просто вставьте в проект, любые изменения не нужно):

    @interface RegistrationViewController : UIViewController {
        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;
    }
    

    П. S: Я надеюсь, что код поможет кому-то быстро добиться желаемого эффекта. (Xcode 4. 5)

    ответ дан HotJard, с репутацией 2290, 12.10.2012
  • 18 рейтинг

    попробуйте этот короткий трюк. , ,

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

    Удачного кодирования :). , , ,

    ответ дан Sourabh Sharma, с репутацией 5123, 11.05.2015
  • 17 рейтинг

    @ user271753

    Чтобы вернуться к оригиналу, добавьте:

    -(BOOL)textFieldShouldReturn:(UITextField *)textField{
       [textField resignFirstResponder];
       [self setViewMovedUp:NO];
       return YES;
    }
    
    ответ дан user436179, с репутацией 41, 29.10.2010
  • 15 рейтинг

    Для перемещения рамки просмотра не требуется представление прокрутки. Вы можете изменить кадр вида viewcontroller's, чтобы весь вид двигался вверх настолько, чтобы поместить текстовое поле первого респондента над клавиатурой. Когда я столкнулся с этой проблемой, я создал подкласс UIViewController, который делает это. Он наблюдает за тем, чтобы на клавиатуре появлялось уведомление, и находил подпредставление первого респондента и (при необходимости) он анимировал основной вид вверх настолько, чтобы первый респондент находился над клавиатурой. Когда клавиатура прячется, она оживляет вид назад, где она была.

    Чтобы использовать этот подкласс, сделайте свой пользовательский контроллер представления подклассом GMKeyboardVC , и он наследует эту функцию (просто убедитесь, что вы реализуете viewWillAppear и viewWillDisappear, они должны вызывать super). Класс на gitub .

    ответ дан progrmr, с репутацией 61410, 10.09.2011
  • 12 рейтинг

    Согласно документам , начиная с iOS 3. 0, класс UITableViewController автоматически изменяет размеры и перемещает свое табличное представление, когда есть встроенное редактирование текстовых полей. Я думаю, что недостаточно поместить текстовое поле внутри UITableViewCell, как указали некоторые.

    Из документов :

    Контроллер табличного представления поддерживает встроенное редактирование строк табличного представления; если, например, строки имеют встроенные текстовые поля в режиме редактирования, прокручивает редактируемую строку над виртуальной клавиатурой, которая отображается.

    ответ дан Dheeraj V.S., с репутацией 13191, 4.10.2012
  • 11 рейтинг

    Здесь Я нашел самое простое решение для обработки клавиатуры.

    Вам нужно просто скопировать-вставить ниже пример кода и изменить текстовое поле или любое представление, которое вы хотите переместить вверх.

    Step-1

    Просто скопируйте и вставьте ниже два метода в вашем контроллере

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

    Step-2

    зарегистрировать & amp; отменить регистрацию уведомлений клавиатуры в viewWillAppear и viewWillDisappear методов соответственно.

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

    Step-3

    Вот часть души, Просто замени свое текстовое поле и измени Высота, на сколько вы хотите двигаться вверх.

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

    Ссылка : ну, Пожалуйста, оцените этого парня , который поделился этим красивым фрагментом кода, чистое решение.

    Надеюсь, это было бы очень полезно кому-то там.

    ответ дан swiftBoy, с репутацией 28510, 19.08.2015
  • 11 рейтинг

    Вот решение по взлому, которое я придумал для конкретной раскладки. Это решение похоже на решение Мэтта Галлахера в том, что оно прокручивает раздел в поле зрения. Я все еще новичок в разработке для iPhone и не знаю, как работают макеты. Таким образом, это взломать.

    Моя реализация должна была поддерживать прокрутку при нажатии на поле, а также прокрутку, когда пользователь выбирает следующий на клавиатуре.

    У меня был UIView с высотой 775. Органы управления в основном разбиты на группы по 3 человека на большом пространстве. Я закончил со следующим макетом IB.

    UIView -> UIScrollView -> [UI Components]
    

    Вот и взломать

    Я установил высоту UIScrollView на 500 единиц больше, чем фактический макет (1250). Затем я создал массив с абсолютными позициями, к которым нужно прокрутиться, и простой функцией, чтобы получить их на основе номера тега 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] ;
    }
    

    Теперь все, что вам нужно сделать, это использовать следующие две строки кода в textFieldDidBeginEditing и textFieldShouldReturn (последняя, ​​если вы создаете навигацию по следующему полю)

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

    Пример.

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

    Этот метод не выполняет «прокрутку назад», как другие методы. Это не было требованием. Опять же, это было для довольно «высокого» UIView, и у меня не было дней, чтобы изучить механизмы внутреннего макета.

    ответ дан Steve McFarlin, с репутацией 3193, 28.03.2010
  • 9 рейтинг

    Swift 4 .

    Вы можете легко перемещаться вверх и вниз UITextField или UIView с UIKeyBoard с Animation 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, 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
        }
    
    }
    
    ответ дан ZAFAR007, с репутацией 786, 26.01.2018
  • 9 рейтинг

    В поисках хорошего учебника для начинающих по этому вопросу, нашёл лучший учебник здесь .

    В примере MIScrollView.h внизу урока обязательно поставьте пробел в

    @property (nonatomic, retain) id backgroundTapDelegate;
    

    как видите.

    ответ дан savagenoob, с репутацией 302, 1.01.2012
  • 9 рейтинг

    Используйте это третье лицо, вам не нужно писать даже одну строку

    https: // github. com / hackiftekhar / IQKeyboardManager

    Скачайте проект и перетащите IQKeyboardManager в свой проект. Если вы обнаружите какие-либо проблемы, пожалуйста, прочитайте README документ.

    Ребята действительно убирают головную боль, чтобы управлять клавиатурой. ,

    Спасибо и удачи!

    ответ дан Arvind Kumar, с репутацией 1878, 12.10.2015
  • 9 рейтинг

    Когда UITextField находится в UITableViewCell, прокрутка должна быть установлена ​​автоматически.

    Если это не так, вероятно, из-за неправильного кода / настройки табличного представления.

    Например, когда я перезагрузил свою длинную таблицу с одним UITextField внизу, как показано ниже,

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

    затем мое текстовое поле внизу было скрыто клавиатурой, которая появилась, когда я щелкнул внутри текстового поля.

    Чтобы исправить это, я должен был сделать это -

    -(void) viewWillAppear:(BOOL)animated
    {
        //add the following line to fix issue
        [super viewWillAppear:animated];
        [self.tableview reloadData];
    }
    
    ответ дан lakersgonna3peat, с репутацией 11, 9.03.2011
  • 8 рейтинг

    Примечание : этот ответ предполагает, что ваш textField находится в scrollView.

    Я предпочитаю иметь дело с этим, используя scrollContentInset и scrollContentOffset вместо того, чтобы возиться с кадрами моего представления.

    Сначала давайте послушаем уведомления клавиатуры

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

    Следующим шагом является сохранение свойства, которое представляет текущий первый респондент (UITextfield / UITextVIew, который в настоящее время имеет клавиатуру).

    Мы используем методы делегата, чтобы установить это свойство. Если вы используете другой компонент, вам понадобится нечто подобное.

    Обратите внимание, что для текстового поля мы установили его в didBeginEditing и для textView в shouldBeginEditing. Это происходит потому, что textViewDidBeginEditing вызывается после UIKeyboardWillShowNotification по какой-то причине.

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

    Наконец, вот волшебство

    - (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;
    }
    
    ответ дан Juraj Petrik, с репутацией 535, 2.07.2014
  • 8 рейтинг

    Это решение с использованием 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
        }
    
    }
    
    ответ дан Homam, с репутацией 3727, 17.12.2014
  • 7 рейтинг

    Попробуйте это:

    -(void)textFieldDidBeginEditing:(UITextField *)sender
    {
        if ([sender isEqual:self.m_Sp_Contact])
        {
            [self.m_Scroller setContentOffset:CGPointMake(0, 105)animated:YES];          
        }
    }
    
    ответ дан user1105624, с репутацией 11, 20.07.2012
  • 7 рейтинг

    Swift 2. 0:

    Добавить представление прокрутки и добавить текстовые поля в верхней части. Сделайте раскадровку ссылок на ВК.

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

    Добавьте эти методы: UITextFieldDelegate & amp; 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,
            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)
    
                })
            }
        }
    
    ответ дан A.G, с репутацией 9857, 16.02.2016
  • 6 рейтинг

    Вот бесплатная библиотека для работы с клавиатурой Приложения для клавиатуры в iPhone-. Вам нужно написать только одну строку кода:

    [AutoScroller addAutoScrollTo:scrollView];
    

    Это здорово, чтобы обрабатывать клавиатуру в формах

    ответ дан user966931, с репутацией 16, 17.12.2012
  • 6 рейтинг

    Необходимо программно добавить представление прокрутки с определенным размером кадра. Вы должны добавить UIScrollViewDelegate в. ч файл. Вы должны включить scrollview, для чего вам нужно написать следующее в viewDidLoad ().

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

    Таким образом, вы можете добавить свои значения x, y, width и height. Я думаю, что это поможет вам.

    ответ дан deepti, с репутацией 131, 11.01.2012
  • 6 рейтинг

    Я думаю, что лучший подход - это использовать протоколно-ориентированное программирование, если вы используете Swift.

    Прежде всего вы должны создать протокол KeyboardCapable, который дает любому UIViewController, который ему соответствует, возможность регистрировать и отменять регистрацию наблюдателей клавиатуры:

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

    Вы заметили постороннее ключевое слово KeyboardAnimatable в приведенном выше фрагменте кода. Это просто название следующего протокола, который нам нужно создать:

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

    Этот протокол KeyboardAnimatable предоставляет всем UIViewController, соответствующим ему два метода, которые будут анимировать весь вид вверх и вниз соответственно.

    Хорошо, так что если KeyboardCapable соответствует KeyboardAnimatable, все UIViewController, соответствующий KeyboardCapable, также соответствует KeyboardAnimatable. Это круто.

    Давайте посмотрим UIViewController, соответствующий KeyboardCapable и реагирующий на события клавиатуры:

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

    Теперь ваш UIViewController будет реагировать на события клавиатуры и в результате будет анимирован.

    Примечание. Если вы хотите использовать пользовательскую анимацию вместо push или pull для представления, вы должны определить пользовательские методы в протоколе KeyboardAnimatable или выполнить их для функций KeyboardCapable. Тебе решать.

    ответ дан Jorge Ramos, с репутацией 766, 17.03.2016
  • 5 рейтинг

    Это очень просто, просто вставьте следующий код в ваш класс и настройте его, если вам нужно.

    -(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); 
    }
    
    ответ дан Mohammad Kamran Usmani, с репутацией 450, 30.03.2016
  • 4 рейтинг

    Вы можете также использовать методы делегата текстового поля. Проверьте ниже код. Это работает для меня, когда помещается текстовое поле в представлении прокрутки.

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

    Примечание: Вы должны изменить cPoint. у - значение 100 согласно вашему мнению.

    ответ дан Ganesh Guturi, с репутацией 1539, 3.12.2012
  • 4 рейтинг

    Вот моя версия с использованием autolayout:

    Идея состоит в том, чтобы просто встроить ваше представление, содержащее текстовые поля / текстовое представление, в UIScrollView, установить ограничение снизу к его суперпредставлению, создать выход и обновить его константу в соответствии с высотой клавиатуры, используя уведомления. Это основано на примере Apple здесь и технической заметке Apple по UIScrollView с использованием AutoLayout здесь .

    1) Вставьте свой View V в UIScrollView S: Если вы уже установили свои константы и подпредставления, вы можете скопировать / вставить свое представление и подпредставления в представление ViewController, а затем внедрить его с помощью редактора - & gt; Вставить меню и, наконец, удалить скопированные виды. )

    2) Установите следующие ограничения:

    • S к началу страницы: 0
    • S внизу руководство по макету: 0
    • S ведет к суперпредставлению: 0
    • S тянется к суперпредставлению: 0

    • В верхнем пространстве для просмотра: 0

    • V нижнее пространство для просмотра: 0
    • V завершающее пространство для superview: 0
    • V ведущее место для superview: 0

    • V равной ширине с S

    • Последний нижний V подвид для superview: 20

    3) Создайте выход из последнего ограничения для вашего контроллера представления

    4) Используйте следующий код:

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

    И тадааааа, работает!

    ответ дан dulgan, с репутацией 5725, 9.10.2014
  • 4 рейтинг

    Есть много доступных ответов, рассказывающих о подходе. Я использовал тот же подход, но реализация не очень хорошая.

    Вот базовая идея . Я внес изменения в метод клавиатурыWasShown.

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

    }

    И добавьте этот метод для инициализации activeField

    - (IBAction)textFieldDidBeginEditing:(UITextField *)sender
    {
    self.activeField = sender;
    }
    
    ответ дан vinksharma, с репутацией 107, 5.08.2014
  • 4 рейтинг

    Гораздо более элегантное решение - использовать подкласс UIView (хотя это не всегда уместно) и пересчитать все ваши подпредставления при смене кадра родителя (и быть умным: пересчитывать их, только если новый размер кадра изменился, я , е. используйте CGRectEqualToRect для сравнения нового кадра при переопределении setFrame и ДО того, как вы вызовете [super setFrame:frame_]). Единственный улов - это то, что UIViewController, который вы намереваетесь использовать, вероятно, должен прослушивать события клавиатуры (или, вы можете сделать это в самом UIView, для удобной инкапсуляции). Но только UIKeyboardWillShowNotification и UIKeyboardWillHideNotification. Это так, чтобы все выглядело гладко (если вы подождете, пока CG позвонит, вы получите момент прерывистости).

    Это имеет преимущество в создании подкласса UIView, который в любом случае делает правильные вещи.

    Наивной реализацией было бы переопределение drawRect: (не), лучше было бы просто использовать layoutSubviews (а затем в UIViewController или что-то еще, что вы можете вызвать [view setNeedsLayout] в ОДНОМ методе, который вызывается для любого шоу или спрятаться).

    Это решение позволяет избежать жесткого кодирования смещения клавиатуры (которое изменится, если они не разделены и т. Д.), А также означает, что ваше представление может быть подпредставлением многих других представлений и при этом отвечать правильно.

    Не стоит жестко кодировать что-то подобное, если нет другого решения. ОС дает вам достаточно информации, если вы все сделали правильно, что вам просто нужно перерисовать с умом (в зависимости от вашего нового размера frame). Это намного чище, и то, как вы, должны делать вещи. (Там может быть даже лучший подход, хотя. )

    ура.

    ответ дан Matt Weaver, с репутацией 109, 30.01.2012
  • 4 рейтинг

    Это вычисление смещения независимо от устройства. Получает перекрытую высоту между клавиатурой и текстовым полем:

    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 - это смещение.

    ответ дан Javier Calatrava Llavería, с репутацией 5567, 22.03.2016
  • 4 рейтинг

    https: // github. com / michaeltyson / TPKeyboardAvoiding скачайте этот файл и добавьте пользовательский класс, так как в вашем табличном представлении он будет управлять всеми вещами, поскольку вам не нужно ничего делать. у этого есть много выбора, Вы можете проверить это для другого также, это - все, что Вы должны избегать клавиатуры

    ответ дан anand madhav, с репутацией 328, 11.08.2014
  • 4 рейтинг

    - это категория UITextfield (и других подобных полей), которую я создал, чтобы текстовое поле избегало клавиатуры, вы должны иметь возможность поместить его в свой контроллер представления как есть, и оно должно работать. Он перемещает весь экран вверх, так что текущее текстовое поле находится над клавиатурой с анимацией

    #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
    

    В вашем приложении Delegate добавьте эту функцию

    [[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];
    }
    
    ответ дан Fonix, с репутацией 8464, 14.03.2014
  • 3 рейтинг

    Пожалуйста, выполните следующие действия.

    1) Объявите следующую переменную в. ч файл.

      {      
             CGFloat animatedDistance;
      }
    

    2) Объявите следующие константы в. м файл.

      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) Используйте делегат UITextField для перемещения вверх / вниз клавиатуры.

      -(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];
           }
     }
    
    ответ дан Himanshu Mahajan, с репутацией 3285, 2.04.2013
  • 3 рейтинг

    Я заворачиваю все в один класс. Просто вызовите эти строки кода, когда ваш viewcontroller загружен:

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

    Вот ссылка на пример проекта:
    https: // github. com / caohuuloc / KeyboardInsetScrollView

    ответ дан Cao Huu Loc, с репутацией 1229, 6.05.2015
  • 3 рейтинг

    Недавно я столкнулся с похожим сценарием при работе с приложением для обмена сообщениями. Я создал пользовательский UIView, который прилипает к верхней части клавиатуры и автоматически выполняет большую часть того, что вам нужно.

    MessageComposerView

    http: // www. thegameengine. орг / WP-содержание / добавления / 2013/11 / message_composer_quad_1. JPG

    Идея этого проекта состояла в том, чтобы создать нечто, функционирующее подобно составному представлению iMessage. AKA:

    • прилипает к верхней части клавиатуры и перемещается к нижней части экрана, когда клавиатура отклонена
    • обрабатывает изменения в тексте
    • обрабатывает повороты

    Для изменения размера / реконфигурации вашего UIScrollView вам нужно использовать следующий необязательный метод делегата:

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

    Он будет вызываться всякий раз, когда кадр изменяется (изменен размер, перемещен, повернут), а также будет указывать продолжительность анимации. Вы можете использовать эту информацию для изменения размера рамки UIScrollView и вставок содержимого по мере необходимости.

    ответ дан alexgophermix, с репутацией 2253, 15.11.2013
  • 3 рейтинг

    Я считаю, что это лучшее решение, следуйте приведенному ниже коду:

    Прикрепите ниже к вашему ограничению Vertical Space - Bottom Layout Guide - TextField.

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

    Второй добавить наблюдателей для клавиатурных уведомлений.

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

    Добавьте это к вашему viewDidLoad

    [self observeKeyboard]; 
    

    Наконец методы, которые обрабатывают изменения клавиатуры.

    - (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];
        }];
    }
    
    ответ дан Manesh, с репутацией 348, 26.02.2015
  • 3 рейтинг

    Гораздо более простой, но в то же время обобщенный способ, как в случае с 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;
    }
    
    ответ дан Sam92, с репутацией 47, 17.07.2016
  • 3 рейтинг

    Простое решение, расширяющее UIViewController

    https: // github. com / damienromito / VisibleFormViewController

    enter image description here

    ответ дан Damien Romito, с репутацией 5108, 22.01.2015
  • 2 рейтинг

    Простое решение и с последним API анимации. Смена происхождения. y к 215, вы можете настроить его в зависимости от того, какое значение вам подходит.

    - (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);
            }];
    
        }
    }
    
    ответ дан Vidhur, с репутацией 94, 22.07.2015