#ios #swift #animation #autolayout #uikit
#iOS #swift #Анимация #автоматическое описание #uikit
Вопрос:
Я пытаюсь анимировать (вверх и вниз) все представления в ViewController, когда пользователь переходит от текстового поля к текстовому полю, где каждое текстовое поле имеет клавиатуру с разной высотой, и я использую автозапуск для позиционирования всех представлений.
У меня есть четыре UITextFields
и три с UIButtons
использованием автозапуска, которые перемещаются вверх и вниз в зависимости от разных клавиатур-высота, моя проблема в том, что по какой-то причине все представления анимируются, как только загружается ViewController, а это не то, что я хочу, я хочу, чтобы они анимировались только тогда, когда высота клавиатуры равнадругое. Анимация выглядит так, как будто она анимирует все размеры и позиции представления, как только загружается ViewController.
Для управления анимацией у меня есть main constraint ( constraintKeyboardHeight
), к которому привязаны все представления для определения их вертикального положения (см. Изображение ниже).
К вашему сведению — Пожалуйста, обратите внимание, что я автоматически фокусирую одно из текстовых полей в viewDidLoad
методе. Я не уверен, имеет ли это какое-то отношение к этому.
Есть идеи? Является ли это нормальным поведением при анимации представлений с ограничениями?
override func viewDidLoad() {
super.viewDidLoad()
oneTextField.becomeFirstResponder()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(UserInputViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil)
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
keyboardHeight = keyboardSize.height 10
UIView.animateWithDuration(3.0, animations: {
self.constraintKeyboardHeight.constant = keyboardHeight
self.view.layoutIfNeeded()
})
}
}
Ответ №1:
Вызов self.view.layoutIfNeeded
вызовет обновление макета для всего, что содержится в представлении. Если это включает в себя вложенные представления, которые вы не хотите анимировать, вам следует добавить все те, которые вы хотите анимировать, в вложенное представление контейнера. Ограничьте вложенное представление контейнера на основе клавиатуры и вызывайте layoutIfNeeded
только это вложенное представление.
Я немного смущен
моя проблема в том, что по какой-то причине все представления анимируются, как только загружается ViewController, а это не то, что я хочу, я хочу, чтобы они анимировались только тогда, когда высота клавиатуры отличается
и я интерпретирую проблему как «все анимированные представления», где вам нужны только некоторые из них. Если проблема больше связана с немедленным анимированием представлений, это, конечно, произойдет, поскольку вы правильно настроили первый ответчик при загрузке представления.
Редактировать: если вы не хотите анимировать при первой загрузке, вы можете добавить свойство var firstLoad = true
к своему контроллеру, а затем изменить вашу клавиатуру, чтобы она отображала функцию следующим образом:
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo [UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
keyboardHeight = keyboardSize.height 10
self.constraintKeyboardHeight.constant = keyboardHeight
if firstLoad {
view.layoutIfNeeded()
firstLoad = false
} else {
UIView.animateWithDuration(3.0, animations: {
self.view.layoutIfNeeded()
})
}
}
}
Вы заметите, что я переместил строку константы ограничения из блока анимации. На самом деле вам не нужна эта строка в блоке анимации, просто layoutIfNeeded
вызов.
Комментарии:
1. @ Connor Neville — Проблема в том, что представления анимируются немедленно, но, по-видимому, это ожидаемое поведение. Если я правильно понимаю, это
self.view.layoutIfNeeded
обновление всех представлений непосредственно в главном представлении из ViewController, но почему анимация применяется ко всем представлениям, положению и размеру, если я указываю только для анимации одного из ограничений? Я ожидал бы анимировать все представления, но только вверх и вниз, чтобы приспособиться к значению этого ограничения.2. Анимация происходит немедленно, потому что клавиатура появляется немедленно, что звучит разумно для меня, но если вы не хотите анимацию при первой загрузке, вы можете установить какой-то логический флаг для первой загрузки. И да, это ожидаемое поведение layoutIfNeeded, потому что одно изменение ограничения может и часто изменяет макет всего представления.
3. @ Connor Neville — Теперь имеет смысл. Еще один вопрос: как я могу отслеживать нагрузки? Это может решить мою проблему, поскольку анимация работает так, как я ожидаю, после первой загрузки. Если это слишком сложно, я добавлю представления в одно представление, как предложено в вашем ответе. Но мне любопытно посмотреть, как это делается. Спасибо.
4. Отредактировал это в моем комментарии.
5. Вы потрясающие, большое спасибо!