Как сделать автоматический прокрутка UIScrollView, когда UITextField становится первым ответчиком

Я видел сообщения вокруг здесь, которые предполагают, что UIScrollViews должен автоматически прокручиваться, если subview UITextField становится первым ответчиком; однако я не могу понять, как заставить это работать.

У меня есть UIViewController, у которого есть UIScrollView, а внутри UIScrollView есть несколько текстовых полей.

Я знаю, как это сделать вручную, если это необходимо; однако, из того, что я читал, кажется, что он имеет автопрокрутку. Помогите пожалуйста.

Ответ 1

Я надеюсь, что этот пример поможет вам Вы можете прокручивать до любой точки по этому коду.

scrollView.contentOffset = CGPointMake(0,0);

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

CGPoint point = textfield.frame.origin ;
scrollView.contentOffset = point 

Это должно сделать трюк,

Но если вы не знаете, когда нужно называть этот код, вы должны изучить методы UITextFieldDelegate

Внедрите этот метод в свой код

- (void)textFieldDidBeginEditing:(UITextField *)textField {
// Place Scroll Code here
}

Надеюсь, вы знаете, как использовать методы делегатов.

Ответ 2

Я знаю, что на этот вопрос уже был дан ответ, но я подумал, что буду делиться кодовой комбинацией, которую я использовал из @Adeel и @Basil, потому что, похоже, для меня отлично работает на iOS 9.

-(void)textFieldDidBeginEditing:(UITextField *)textField {

    // Scroll to the text field so that it is
    // not hidden by the keyboard during editing.
    [scroll setContentOffset:CGPointMake(0, (textField.superview.frame.origin.y + (textField.frame.origin.y))) animated:YES];
}

-(void)textFieldDidEndEditing:(UITextField *)textField {

    // Remove any content offset from the scroll
    // view otherwise the scroll view will look odd.
    [scroll setContentOffset:CGPointMake(0, 0) animated:YES];
}

Я также использовал анимированный метод, который делает намного более плавный переход.

Ответ 3

Вы ничего не должны делать вручную. Это поведение по умолчанию. Есть две возможности, почему вы не видите поведение

  1. Наиболее вероятная причина в том, что клавиатура UITextField ваш UITextField. Смотрите решение ниже
  2. Другая возможность состоит в том, что у вас есть другой UIScrollView где-то в иерархии представлений между UITextField и UIScrollView который вы хотите автоматически прокручивать. Это менее вероятно, но все еще может вызвать проблемы.

Для # 1 вы хотите реализовать что-то похожее на рекомендации Apple по перемещению контента, расположенного под клавиатурой. Обратите внимание, что код, предоставленный Apple, не учитывает ротацию. Для улучшений в их коде, проверьте реализацию этого сообщения в блоге метода keyboardDidShow который правильно переводит кадр клавиатуры, используя окно.

Ответ 4

Вот обновление Swift 4 для ответа @Supertecnoboff. Это отлично сработало для меня.

func textFieldDidBeginEditing(_ textField: UITextField) {
    scroll.setContentOffset(CGPoint(x: 0, y: (textField.superview?.frame.origin.y)!), animated: true)
}

func textFieldDidEndEditing(_ textField: UITextField) {
    scroll.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
}

Удостоверьтесь, чтобы расширить UITextFieldDelegate и установить делегата текстовых полей на себя.

Ответ 5

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGRect rect = [textField bounds];
    rect = [textField convertRect:rect toView:self.scrollView];
    rect.origin.x = 0 ;
    rect.origin.y -= 60 ;
    rect.size.height = 400;

    [self.scrollView scrollRectToVisible:rect animated:YES];
}

Ответ 6

Вы можете использовать эту функцию для autoScroll из UITextField

on UITextFieldDelegate

- (void)textFieldDidBeginEditing:(UITextField *)textField {

[self autoScrolTextField:textField onScrollView:self.scrollView];
}




- (void) autoScrolTextField: (UITextField *) textField onScrollView: (UIScrollView *) scrollView { 
 float slidePoint = 0.0f;
float keyBoard_Y_Origin = self.view.bounds.size.height - 216.0f;
float textFieldButtomPoint = textField.superview.frame.origin.y + (textField.frame.origin.y + textField.frame.size.height);

if (keyBoard_Y_Origin < textFieldButtomPoint - scrollView.contentOffset.y) {
    slidePoint = textFieldButtomPoint - keyBoard_Y_Origin + 10.0f;
    CGPoint point = CGPointMake(0.0f, slidePoint);
    scrollView.contentOffset = point;
}

EDIT:

Теперь я использую IQKeyboardManager Престижность разработчику этого, вам нужно попробовать это.

Ответ 7

Если у вас есть несколько текстовых полей, скажите Textfield1, Textfield2, Textfield3 и вы хотите прокрутить прокрутку по оси y, когда textfield2 становится первым ответчиком:

if([Textfield2 isFirstResponder])
{
    scrollView.contentOffset = CGPointMake(0,yourY);
} 

Ответ 8

Как упоминал Майкл Макгуайр в своем пункте № 2 выше, поведение системы по умолчанию ведет себя неправильно, когда представление прокрутки содержит другое представление прокрутки между текстовым полем и представлением прокрутки. Я обнаружил, что неправильное поведение также происходит, когда рядом с текстовым полем находится представление прокрутки (оба встроены в представление прокрутки, которое необходимо настроить, чтобы текстовое поле отображалось, когда текстовое поле хочет начать редактирование. на iOS 12.1.

Но мое решение отличается от вышеуказанного. В моем виде прокрутки верхнего уровня, который подклассифицирован, так что я могу добавлять свойства и переопределять методы, я переопределяю scrollRectToVisible:animated: Он просто вызывает его [super scrollRectToVisible:animated:] если только не существует набора свойств, который указывает ему корректировать переданный rect, который является рамкой текстового поля. Когда свойство не ноль, это ссылка на рассматриваемый UITextField, а rect настраивается так, что представление прокрутки идет дальше, чем думала система. Поэтому я поместил это в файл подкласса UIScrollView:

@property (nullable) UITextField *textFieldToBringIntoView;

(с соответствующим @synthesize textFieldToBringIntoView; в реализации. Затем я добавил этот метод переопределения в реализацию:

- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)how
{
    if (textFieldToBringIntoView) {
       // Do whatever mucking with 'rect' origin needed to make it visible
       // based on context or its spatial relationship with the other
       // view that the system is getting confused by.

       textFieldToBringIntoView = nil;        // Go back to normal
       }
    [super scrollRectToVisible:rect animated:how];
}

В методе делегата для UITextField когда он собирается начать редактирование, просто установите textFieldToBringIntoView для рассматриваемого textField:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    // Ensure it scrolls into view so that keyboard doesn't obscure it
    // The system is about to call |scrollRectIntoView:| for the scrolling
    // superview, but the system doesn't get things right in certain cases.

    UIScrollView *parent = (UIScrollView *)textField.superview;
    // (or figure out the parent UIScrollView some other way)

    // Tell the override to do something special just once
    // based on this text field position in its parent scroll view.
    parent.textFieldToBringIntoView = textField;
    // The override function will set this back to nil

    return(YES);
}

Вроде работает. И если Apple исправит их ошибку, похоже, что она все еще может работать (скрестив пальцы).

Ответ 9

Я добавляю textFiled в UIScrollView и изменяю содержимое, когда длина содержимого изменяется, и перехватываю некоторое событие, которое textFiled может выполнять как собственное. Вы можете проверить мое демо, если вам нужно.https://github.com/sunshuyao/ScrollableTextField