Я испытываю странное поведение при анимации высоты вспомогательного представления ввода. Что я делаю не так?
Я создаю подкласс UIInputView
(InputView
) с одним подпредставлением. Высота InputView
и его intrinsicContentSize
контролируется подпредставлением. InputView
имеет высоту 50 пикселей, когда isVisible
равно true
, и 0 пикселей, если isVisible
равно false.
import UIKit
class InputView: UIInputView {
private let someHeight: CGFloat = 50.0, zeroHeight: CGFloat = 0.0
private let subView = UIView()
private var hide: NSLayoutConstraint?, show: NSLayoutConstraint?
var isVisible: Bool {
get {
return show!.isActive
}
set {
// Always deactivate constraints before activating conflicting ones
if newValue == true {
hide?.isActive = false
show?.isActive = true
} else {
show?.isActive = false
hide?.isActive = true
}
}
}
// MARK: Sizing
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: size.width, height: someHeight)
}
override var intrinsicContentSize: CGSize {
return CGSize.init(width: bounds.size.width, height: subView.bounds.size.height)
}
// MARK: Initializers
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect, inputViewStyle: UIInputViewStyle) {
super.init(frame: frame, inputViewStyle: inputViewStyle)
addSubview(subView)
subView.backgroundColor = UIColor.purple
translatesAutoresizingMaskIntoConstraints = false
subView.translatesAutoresizingMaskIntoConstraints = false
subView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
subView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
subView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
subView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor).isActive = true
show = subView.heightAnchor.constraint(equalToConstant: someHeight)
hide = subView.heightAnchor.constraint(equalToConstant: zeroHeight)
hide?.isActive = true
}
}
Контроллер основного представления переключает isVisible
в односекундном блоке анимации при нажатии кнопки.
import UIKit
class MainViewController: UIViewController {
let testInputView = InputView.init(frame: .zero, inputViewStyle: .default)
@IBAction func button(_ sender: AnyObject) {
UIView.animate(withDuration: 1.0) {
let isVisible = self.testInputView.isVisible
self.testInputView.isVisible = !isVisible
self.testInputView.layoutIfNeeded()
}
}
override var canBecomeFirstResponder: Bool {
return true
}
override var inputAccessoryView: UIView? {
return testInputView
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Я ожидаю, что входное вспомогательное представление будет плавно увеличиваться от нижней части экрана, когда isVisible
установлено на true
, и плавно сжиматься до кнопки экрана, когда isVisible
установлено на false
. Вместо этого фоновое наложение клавиатуры отображается на полной высоте 50 пикселей, как только isVisible
становится true
, а вид вспомогательного ввода увеличивается из центра его фрейма.
При сжатии входной вспомогательный вид мгновенно теряет часть своей высоты, прежде чем плавно продолжить анимацию.
Я создал демонстрационный проект ввода вспомогательного представления, который демонстрирует это неожиданное поведение.