С iOS SDK:
У меня есть UIView
с, UITextField
которые поднимают клавиатуру. Мне нужно, чтобы я мог:
Разрешить прокрутку содержимого,
UIScrollView
чтобы увидеть другие текстовые поля, как только клавиатураАвтоматически «прыгать» (путем прокрутки вверх) или сокращения
Я знаю, что мне нужно UIScrollView
. Я пытался изменить класс своего класса UIView
на a, 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
}
Тем не менее, это автоматически не «двигает вверх» и не центрирует нижние текстовые поля в видимой области, что мне бы очень хотелось.
источник
Ответы:
Вам понадобится только
ScrollView
если содержимое, которое у вас сейчас есть, не помещается на экране iPhone. (Если вы добавляетеScrollView
как суперпредставление компонентов просто дляTextField
прокрутки вверх, когда клавиатура появляется, то это не нужно.)Стандартный способ предотвратить
TextField
наложение клавиатуры на клавиатуру - это перемещать изображение вверх / вниз, когда отображается клавиатура.Вот пример кода:
источник
textFieldDidBeginEditing
раздел.У меня также было много проблем с
UIScrollView
созданием несколькихUITextFields
, из которых один или несколько из них были бы скрыты клавиатурой при редактировании.Вот некоторые вещи, которые следует учитывать, если вы
UIScrollView
не прокручиваете их должным образом.1) Убедитесь, что ваш contentSize больше
UIScrollView
размера кадра. Способ понятьUIScrollViews
, чтоUIScrollView
это похоже на окно просмотра контента, определенного в contentSize. Поэтому, когда дляUIScrollview
прокрутки в любом месте, contentSize должен быть больше, чемUIScrollView
. Иначе, прокрутка не требуется, так как все, что определено в contentSize, уже видно. Кстати, по умолчанию contentSize =CGSizeZero
.2) Теперь, когда вы понимаете, что на
UIScrollView
самом деле окно в ваш «контент», способ гарантировать, что клавиатура не заслоняет вашеUIScrollView's
«окно» просмотра, состоит в изменении размераUIScrollView
так, чтобы при наличии клавиатуры у вас былоUIScrollView
окно по размеру соответствует только оригинальномуUIScrollView
frame.size.height минус высота клавиатуры. Это гарантирует, что ваше окно будет только этой маленькой видимой областью.3) Вот подвох: когда я впервые реализовал это, я подумал, что мне нужно получить
CGRect
отредактированное текстовое поле и вызватьUIScrollView's
метод scrollRecToVisible. Я реализовалUITextFieldDelegate
методtextFieldDidBeginEditing
с помощью вызоваscrollRecToVisible
метода. Это на самом деле работали со странным побочным эффектом , что скроллинг будет оснасткойUITextField
в положение. Долгое время я не мог понять, что это было. Затем я прокомментировалtextFieldDidBeginEditing
метод Delegate, и все это работает !! (???). Как выяснилось, я считаю, чтоUIScrollView
фактически неявно переносит редактируемоеUITextField
в настоящее время в видимое окно неявно. Моя реализацияUITextFieldDelegate
метода и последующий вызов к немуscrollRecToVisible
были излишни и стали причиной странного побочного эффекта.Так вот шаги , чтобы правильно прокручивает
UITextField
вUIScrollView
на место , когда появляется значок клавиатуры.viewDidLoad
viewDidUnload
contentSize
установлено и больше, чем у васUIScrollView
вviewDidLoad
UIScrollView
, когда клавиатура присутствуетUIScrollView
когда клавиатура уходит.UITextField
это закладками , даже если клавиатура уже присутствует , чтобы избежать усадкиUIScrollView
, когда он уже усадкеСтоит отметить, что при
UIKeyboardWillShowNotification
срабатывании другой клавиши она будет срабатывать даже тогда, когда клавиатура уже находится на экранеUITextField
. Я позаботился об этом, используя ivar, чтобы избежать изменения размера,UIScrollView
когда клавиатура уже находится на экране. Случайное изменение размера,UIScrollView
когда клавиатура уже есть, будет катастрофическим!Надеюсь, этот код избавит некоторых из вас от головной боли.
источник
UIKeyboardBoundsUserInfoKey
устарела. 2. keyboardSize находится в «координатах экрана», поэтому ваши вычисления в viewFrame завершатся неудачно, если кадр будет повернут или масштабирован.CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
вместо устаревшегоUIKeyboardBoundsUserInfoKey
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size
должно быть[[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size
. Отличное решение, хотя!На самом деле лучше всего использовать реализацию Apple, как указано в документации . Однако код, который они предоставляют, неисправен. Замените часть, найденную
keyboardWasShown:
чуть ниже комментариев, на следующую:Проблемы с кодом Apple заключаются в следующем: (1) Они всегда вычисляют, находится ли точка в рамке представления, но это так
ScrollView
, поэтому она, возможно, уже прокрутилась, и вам необходимо учитывать это смещение:(2) Они смещают contentOffset на высоту клавиатуры, но мы хотим наоборот (мы хотим сместить
contentOffset
высоту, которая видна на экране, а не то, что нет):источник
UIKeyboardFrameEndUserInfoKey
вместоUIKeyboardFrameBeginUserInfoKey
получения размера клавиатуры, так как это подберет такие вещи, как пользовательские изменения клавиатуры и включение / выключение интеллектуального текста.self.scrollView.contentOffset = self.currentSVoffset;
В
textFieldDidBeginEditting
и вtextFieldDidEndEditing
вызове функции[self animateTextField:textField up:YES]
так:Я надеюсь, что этот код поможет вам.
В Свифт 2
SWIFT 3
источник
[UIView animateWithDuration: animations:^{ }];
?Просто используя TextFields:
1a) Использование
Interface Builder
: Выбрать все TextFields => Edit => Embed In => ScrollView1b) Внедрение TextFields в UIScrollView, называемое scrollView.
2) Установить
UITextFieldDelegate
3) Установите каждый
textField.delegate = self;
(или установите соединения вInterface Builder
)4) Копировать / Вставить:
источник
textField
он уже виден.CGPointMake(0, textField.frame.origin.y);
наCGPointMake(0, textField.frame.origin.y + scrollView.contentInset.top);
Для универсального решения , вот мой подход к реализации IQKeyboardManager .
Шаг1: - Я Добавленные глобальные уведомления о
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 и многое другое, чем вы думаете.
источник
Я соединил универсальное, дроп-ин
UIScrollView
,UITableView
и дажеUICollectionView
подкласс , который заботится о перемещении всех текстовых полей внутри него в сторону клавиатуры.Когда клавиатура должна появиться, подкласс найдет подпредставление, которое должно быть отредактировано, и отрегулирует его фрейм и смещение содержимого, чтобы убедиться, что представление является видимым, с анимацией, соответствующей всплывающему окну клавиатуры. Когда клавиатура исчезает, она восстанавливает свой прежний размер.
Он должен работать практически с любой настройкой, либо с
UITableView
интерфейсом на основе , либо с интерфейсом, состоящим из представлений, размещенных вручную.Вот это: решение для перемещения текстовых полей с клавиатуры
источник
Это все сделает за вас, просто поместите их в ваш класс контроллера представления и реализуйте в
UITextFieldDelegate
вашем контроллере представления и установите делегата textField вself
Реализуйте методы обратного вызова делегата:
Для Swift 4, 4.2, 5: изменить
в
Последнее замечание об этой реализации: если вы поместите другой контроллер представления в стек, пока отображается клавиатура, это создаст ошибку, когда представление возвращается к его центральной рамке, но смещение клавиатуры не сбрасывается. Например, ваша клавиатура является первым респондентом для nameField, но затем вы нажимаете кнопку, которая помещает ваш Help View Controller в ваш стек. Чтобы исправить ошибку смещения, обязательно вызовите nameField.resignFirstResponder () перед выходом из контроллера представления, убедившись, что метод делегата textFieldDidEndEditing также вызывается. Я делаю это в методе viewWillDisappear.
источник
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
поэтому я изменил эту строку наself.view.frame.offsetInPlace(dx: 0, dy: movement)
Уже есть много ответов, но все же ни одно из вышеприведенных решений не имело всех причудливых средств позиционирования, необходимых для «идеальной» безошибочной, обратно совместимой и не мерцающей анимации. (ошибка при анимации frame / bounds и contentOffset вместе, различные ориентации интерфейса, разделенная клавиатура iPad, ...)
Позвольте мне поделиться своим решением:
(при условии, что вы настроили
UIKeyboardWill(Show|Hide)Notification
)источник
UIApplication.shared.sendAction(...)
. Вот версия вашего ответа Swift 3 (за исключением части willHide), сsendAction
внедренным: gist.github.com/xaphod/7aab1302004f6e933593a11ad8f5a72dШиун сказал: «Как оказалось, я полагаю, что UIScrollView фактически неявно переносит редактируемый в настоящий момент UITextField в видимое окно». Это, похоже, верно для iOS 3.1.3, но не для 3.2, 4.0 или 4.1. Мне пришлось добавить явный scrollRectToVisible, чтобы сделать UITextField видимым на iOS> = 3.2.
источник
[UITextField scrollTextFieldToVisibleIfNecessary]
метод, который в свою очередь вызывает[UIScrollView scrollRectToVisible]
когда[UITextField becomeFirstResponder]
вызывается. См. Github.com/leopatras/ios_textfields_on_scrollview . Если ограничения и контроллеры представления установлены правильно, фактически нет необходимости вызыватьscrollRectToVisible
явно (по крайней мере, начиная с IOS 11).Одна вещь, чтобы рассмотреть, хотите ли вы когда-либо использовать
UITextField
самостоятельно. Я не сталкивался ни с какими хорошо разработанными приложениями для iPhone, которые действительно используютUITextFields
за пределамиUITableViewCells
.Это будет некоторая дополнительная работа, но я рекомендую вам реализовать все представления ввода данных в виде таблиц. Добавьте
UITextView
к своемуUITableViewCells
.источник
UITableView
к сожалению, единственный путь. Уведомления клавиатуры хрупкие и со временем изменились. Пример кода для переполнения стека: stackoverflow.com/a/32390936/218152Этот документ подробно описывает решение этой проблемы. Посмотрите на исходный код в разделе «Перемещение содержимого, расположенного под клавиатурой». Это довольно просто.
РЕДАКТИРОВАТЬ: заметил, что в примере есть крошечный глюк. Вы, вероятно, захотите слушать
UIKeyboardWillHideNotification
вместоUIKeyboardDidHideNotification
. В противном случае представление прокрутки позади клавиатуры будет обрезано на время анимации закрытия клавиатуры.источник
Самое простое решение найдено
источник
int movement = (up ? -movementDistance : movementDistance);
if (textField.frame.origin.y < self.view.frame.size.height - keyboard.height) { movementDistance = 0 }
Пожалуйста, обратите внимание, чтоkeyboard
переменная - это CGRect клавиатуры, которая появляется, когда вы получаете:let keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey]!.CGRectValue())!
Небольшое исправление, которое работает для многих UITextFields
источник
rect.origin.y=+currTextField.frame.origin.y
работает хорошо, спасибоКод RPDP успешно перемещает текстовое поле с клавиатуры. Но когда вы прокручиваете до верха после использования и отклонения клавиатуры, верхняя часть прокручивается вверх из вида. Это верно для симулятора и устройства. Чтобы прочитать содержимое в верхней части этого представления, необходимо перезагрузить представление.
Разве его следующий код не должен вернуть представление вниз?
источник
Я не уверен, что перемещение представления вверх является правильным подходом, я сделал это другим способом, изменив размер UIScrollView. Я объяснил это подробно в маленькой статье
источник
Чтобы вернуть исходное состояние просмотра, добавьте:
источник
Попробуйте этот короткий трюк.
источник
Там так много решений, но я потратил несколько часов, прежде чем он заработал. Итак, я поместил этот код здесь (просто вставьте в проект, никаких изменений не нужно):
PS: я надеюсь, что код поможет кому-то быстро добиться желаемого эффекта. (Xcode 4.5)
источник
@ user271753
Чтобы вернуться к исходному виду, добавьте:
источник
Для перемещения рамки просмотра не требуется представление прокрутки. Вы можете изменить рамку
viewcontroller's
вида так, чтобы весь вид двигался вверх настолько, чтобы поместить текстовое поле первого респондента над клавиатурой. Когда я столкнулся с этой проблемой, я создал подклассUIViewController
который делает это. Он наблюдает за тем, чтобы на клавиатуре появлялось уведомление, и находил подпредставление первого респондента и (при необходимости) он анимировал основной вид вверх настолько, чтобы первый респондент находился над клавиатурой. Когда клавиатура скрывается, она оживляет вид назад, где она была.Чтобы использовать этот подкласс, сделайте свой собственный контроллер представления подклассом GMKeyboardVC, и он наследует эту функцию (просто убедитесь, что вы реализуете,
viewWillAppear
иviewWillDisappear
они должны вызывать super). Класс на github .источник
Свифт 4 .
Вы можете легко перемещаться вверх и вниз
UITextField
ИлиUIView
СUIKeyBoard
WithAnimation
источник
Вот хакерское решение, которое я придумал для конкретного макета. Это решение похоже на решение Мэтта Галлахера в том смысле, что оно отображает раздел. Я все еще новичок в разработке для iPhone, и не знаю, как работают макеты. Таким образом, это взломать.
Моя реализация должна была поддерживать прокрутку при нажатии на поле, а также прокрутку, когда пользователь выбирает следующий на клавиатуре.
У меня был UIView с высотой 775. Элементы управления распределены в основном группами по 3 на большом пространстве. Я закончил со следующим макетом IB.
Здесь приходит взломать
Я установил высоту UIScrollView на 500 единиц больше, чем фактический макет (1250). Затем я создал массив с абсолютными позициями, к которым нужно прокрутиться, и простой функцией для получения их на основе номера тега IB.
Теперь все, что вам нужно сделать, это использовать следующие две строки кода в textFieldDidBeginEditing и textFieldShouldReturn (последняя, если вы создаете навигацию по следующему полю)
Пример.
Этот метод не «прокручивает назад», как другие методы. Это не было требованием. Опять же, это было для довольно «высокого» UIView, и у меня не было дней, чтобы изучить механизмы внутреннего макета.
источник
Согласно документам , начиная с iOS 3.0,
UITableViewController
класс автоматически изменяет размеры и перемещает свое табличное представление, когда есть встроенное редактирование текстовых полей. Я думаю, что недостаточно поместить текстовое поле внутриUITableViewCell
как указали некоторые.Из документов :
источник
Вам нужно просто скопировать и вставить ниже пример кода и изменить текстовое поле или любое представление, которое вы хотите переместить вверх.
Шаг 1
Шаг 2
Шаг 3
Ссылка : хорошо, пожалуйста, оцените этого парня , который поделился этим красивым фрагментом кода, чистым решением.
Надеюсь, это кому-то очень поможет.
источник
В поисках хорошего учебника для начинающих по этому вопросу, нашел лучший учебник здесь .
В
MIScrollView.h
примере внизу урока обязательно поставьте пробел вкак видишь.
источник
Когда
UITextField
естьUITableViewCell
прокрутка должна быть настроена автоматически.Если это не так, вероятно, из-за неправильного кода / настройки таблицы.
Например, когда я перезагрузил свою длинную таблицу с одной
UITextField
внизу, как показано ниже,затем мое текстовое поле внизу было скрыто клавиатурой, которая появилась, когда я щелкнул внутри текстового поля.
Чтобы исправить это, я должен был сделать это -
источник
viewWillAppear
не вызывается. ИreloadData
не делает затемненные строки видимыми.Используйте это третье лицо, вам не нужно писать даже одну строку
https://github.com/hackiftekhar/IQKeyboardManager
скачать проект и перетащить
IQKeyboardManager
в свой проект. Если вы обнаружите какие-либо проблемы, пожалуйста, прочитайтеREADME
документ.Ребята действительно убирают головную боль, чтобы управлять клавиатурой.
источник
Примечание : этот ответ предполагает, что ваш textField находится в scrollView.
Я предпочитаю иметь дело с этим, используя scrollContentInset и scrollContentOffset вместо того, чтобы возиться с кадрами моего представления.
Сначала давайте послушаем уведомления клавиатуры
Следующим шагом является сохранение свойства, которое представляет текущий первый респондент (UITextfield / UITextVIew, который в настоящее время имеет клавиатуру).
Мы используем методы делегата, чтобы установить это свойство. Если вы используете другой компонент, вам понадобится нечто подобное.
Обратите внимание, что для текстового поля мы устанавливаем его в didBeginEditing, а для textView - в mustBeginEditing. Это потому, что textViewDidBeginEditing вызывается после UIKeyboardWillShowNotification по какой-то причине.
Наконец, вот волшебство
источник
Это решение с использованием Swift.
источник