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

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

Дубликат rdar: // 16538222 over

Основываясь на ответе Моше …

Подclass UIScrollView и переопределить следующий метод:

 - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated 

Оставьте его пустым. Работа выполнена!

Я боролся с той же проблемой, и наконец нашел решение.

Я исследовал, как выполняется автоматический прокрутка, отслеживая трассировку вызова, и обнаружил, что внутренний [UIFieldEditor scrollSelectionToVisible] вызывается, когда буква вводится в UITextField . Этот метод, похоже, действует на UIScrollView ближайшего предка UITextField .

Таким образом, в textFieldDidBeginEditing , обертывая UITextField новым UIScrollView с тем же размером (то есть вставляя представление между UITextField и его супервидом), это блокирует автоматическую прокрутку. Наконец, удалите эту оболочку на textFieldDidEndEditing .

Код выглядит следующим образом:

 - (void)textFieldDidBeginEditing:(UITextField*)textField { UIScrollView *wrap = [[[UIScrollView alloc] initWithFrame:textField.frame] autorelease]; [textField.superview addSubview:wrap]; [textField setFrame:CGRectMake(0, 0, textField.frame.size.width, textField.frame.size.height)]; [wrap addSubview: textField]; } - (void)textFieldDidEndEditing:(UITextField*)textField { UIScrollView *wrap = (UIScrollView *)textField.superview; [textField setFrame:CGRectMake(wrap.frame.origin.x, wrap.frame.origin.y, wrap.frame.size.width, textField.frame.size.height)]; [wrap.superview addSubview:textField]; [wrap removeFromSuperview]; } 

надеюсь это поможет!

У меня была та же проблема с отключением автоматической прокрутки UITextView являющейся ячейкой UITableView . Я смог решить это, используя следующий подход:

 @interface MyTableViewController : UITableViewController @implementation MyTableViewController { BOOL preventScrolling; // ... } // ... set self as the delegate of the text view - (void)textViewDidBeginEditing:(UITextView *)textView { preventScrolling = YES; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (preventScrolling) { [self.tableView setContentOffset:CGPointMake(0, -self.tableView.contentInset.top) animated:NO]; } } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { preventScrolling = NO; } 

Определение scrollViewWillBeginDragging используется для восстановления поведения прокрутки по умолчанию, когда сам пользователь инициирует прокрутку.

Как упоминал UITextField , когда UITextField первым ответчиком, его первое родительское представление типа UIScrollView (если оно существует) прокручивается, чтобы сделать видимым UITextField . Самый простой взлом – просто обернуть каждый UITextField в UIScrollView (или, в идеале, обернуть все их в один манекен UIScrollView ). Это очень похоже на решение Taketo, но оно должно дать вам немного лучшую производительность, и я буду держать ваш код (или ваш интерфейс в Interface Builder) более чистым, на мой взгляд.

Это похоже на UIScrollview, который содержит UITextfield, автоматически настраивает смещение содержимого; когда текстовое поле станет первым ответчиком. Это можно решить, добавив сначала текстовое поле в scrollview того же размера, а затем добавив его в основное представление прокрутки. вместо прямого добавления в основное scrollview

  // Swift let rect = CGRect(x: 0, y: 0, width: 200, height: 50) let txtfld = UITextField() txtfld.frame = CGRect(x: 0, y: 0, width: rect.width, height: rect.height) let txtFieldContainerScrollView = UIScrollView() txtFieldContainerScrollView.frame = rect txtFieldContainerScrollView.addSubview(txtfld) // Now add this txtFieldContainerScrollView in desired UITableViewCell, UISCrollView.. etc self.mainScrollView.addSubview(txtFieldContainerScrollView) // Am33T 

Основываясь на ответе Луки, чтобы решить проблему, что его решение полностью отключает автопрокрутку, вы можете отключить его выборочно следующим образом:

 // TextFieldScrollView #import  @interface TextFieldScrollView : UIScrollView @property (assign, nonatomic) IBInspectable BOOL preventAutoScroll; @end @implementation TextFieldScrollView - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated { if (self.preventAutoScroll == NO) { [super scrollRectToVisible:rect animated:animated]; } } @end 

Таким образом, вы можете полностью настроить его в интерфейсе Builder, чтобы отключить автопрокрутку, но в любой момент можете полностью включить его, чтобы снова включить его (хотя почему вы хотите, чтобы это было за пределами меня).

Так я это делаю:

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

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

 #import  @protocol ExtendedScrollViewDelegate  - (CGPoint)scrollView:(UIScrollView*)scrollView offsetForScrollingToVisibleRect:(CGRect)rect; @end @interface ExtendedScrollView : UIScrollView @property (nonatomic, unsafe_unretained) id scrollToVisibleDelegate; @end #import "ExtendedScrollView.h" @implementation ExtendedScrollView - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated { if (_scrollToVisibleDelegate && [_scrollToVisibleDelegate respondsToSelector:@selector(scrollView:offsetForScrollingToVisibleRect:)]) { [self setContentOffset:[_scrollToVisibleDelegate scrollView:self offsetForScrollingToVisibleRect:rect] animated:animated]; } else { [super scrollRectToVisible:rect animated:animated]; } } @end 

Я пробовал ответить @ TaketoSano, но, похоже, не работает. Мое дело в том, что у меня нет scrollview, просто просмотр с несколькими текстовыми полями.

И, наконец, у меня есть обходной путь. Для клавиатуры нужны два имени по умолчанию:

  • UIKeyboardDidShowNotification когда клавиатура действительно показывала;
  • UIKeyboardWillHideNotification когда клавиатура скроется.

Вот пример кода, который я использовал:

 - (void)viewDidLoad { [super viewDidLoad]; ... NSNotificationCenter * notificationCetner = [NSNotificationCenter defaultCenter]; [notificationCetner addObserver:self selector:@selector(_keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; [notificationCetner addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } - (void)_keyboardWasShown:(NSNotification *)note { [self.view setFrame:(CGRect){{272.f, 55.f}, {480.f, 315.f}}]; } - (void)_keyboardWillHide:(NSNotification *)note { [self.view setFrame:(CGRect){{272.f, 226.5f}, {480.f, 315.f}}]; } 

Здесь (CGRect){{272.f, 226.5f}, {480.f, 315.f}} является кадром по умолчанию, когда клавиатура скрыта. И (CGRect){{272.f, 55.f}, {480.f, 315.f}} – это рамка представления, когда клавиатура действительно показывала.

И btw, изменение frameworks представления будет автоматически применено к анимации, это действительно прекрасно!

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

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // This is solving the issue where making the text field first responder // automatically scrolls the scrollview down by the height of the search bar. if (!scrollView.isDragging && !scrollView.isDecelerating && self.searchField.isFirstResponder && (scrollView.contentOffset.y < -scrollView.contentInset.top)) { [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, -scrollView.contentInset.top) animated:NO]; } } 

Я не знаю какого-либо свойства UIScrollView , которое позволит это. Было бы плохой пользовательский интерфейс, чтобы иметь возможность отключить это, ИМХО.

Тем не менее, может быть возможным подclass UIScrollView и переопределить некоторые из его методов, чтобы проверить, что UITextfield не является первым ответчиком перед прокруткой.

Более простой способ остановить прокрутку прокрутки, когда вы выбираете textField, находится в вашем viewController :: viewWillAppear () НЕ вызывать [super viewWillAppear];

Затем вы можете управлять прокруткой по своему усмотрению.

  • Как вы отключаете клавиатуру при редактировании UITextField
  • Отключить клавиатуру UITextField?
  • Сохранение объекта поверх клавиатуры в случае старта FirstResponder или resignFirstResponder?
  • Установить дополнение для UITextField с помощью UITextBorderStyleNone
  • Обнаружение backspace в пустом UITextField
  • Обложки iPhone для iPhone UITextField
  • Как отменить клавиатуру iOS программно при нажатии возврата
  • UITextField: перемещение вида при появлении клавиатуры
  • Давайте будем гением компьютера.