iOS Autolayout: странное расширение-анимация UITextView внутри UIScrollView - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь анимировать ограничение высоты UITextView внутри UIScrollView. Когда пользователь нажимает кнопку «переключатель», текст должен отображаться в анимации сверху вниз. Но каким-то образом UIKit исчезает в полном виде.

Animation

Для обеспечения высоты «dynamici c» в зависимости от intrinsi c content-size Я деактивирую ограничение высоты, установленное на ноль.

 @IBAction func toggle() {
    layoutIfNeeded()
    UIView.animate(withDuration: 0.6, animations: { [weak self] in

        guard let self = self else {
            return
        }

        if self.expanded {
            NSLayoutConstraint.activate([self.height].compactMap { $0 })
        } else {
            NSLayoutConstraint.deactivate([self.height].compactMap { $0 })
        }
        self.layoutIfNeeded()
    })
    expanded.toggle()
}

Полный код этого примера доступен на моем репозитории GitHub: ScrollAnimationExample

1 Ответ

1 голос
/ 08 апреля 2020

Просмотр вашего репозитория GitHub ...

Проблема связана с анимацией view. Вы хотите запустить .animate() в самом верхнем представлении в иерархии.

Для этого вы можете создать новое свойство вашего ExpandableView, например:

var topMostView: UIView?

и затем установите это свойство из контроллера представления, или ...

Чтобы сохранить класс инкапсулированным, позвольте ему найти самый верхний вид. Замените toggle() веселье c на:

@IBAction func toggle() {

    // we need to run .animate() on the "top" superview

    // make sure we have a superview
    guard self.superview != nil else {
        return
    }

    // find the top-most superview
    var mv: UIView = self
    while let s = mv.superview {
        mv = s
    }

    // UITextView has subviews, one of which is a _UITextContainerView,
    //  which also has a _UITextCanvasView subview.
    // If scrolling is disabled, and the TextView's height is animated to Zero,
    //  the CanvasView's height is instantly set to Zero -- so it disappears instead of animating.

    // So, when the view is "expanded" we need to first enable scrolling,
    //  and then animate the height (to Zero)
    // When the view is NOT expanded, we first disable scrolling
    //  and then animate the height (to its intrinsic content height)

    if expanded {
        textView.isScrollEnabled = true
        NSLayoutConstraint.activate([height].compactMap { $0 })
    } else {
        textView.isScrollEnabled = false
        NSLayoutConstraint.deactivate([height].compactMap { $0 })
    }

    UIView.animate(withDuration: 0.6, animations: {
        mv.layoutIfNeeded()
    })

    expanded.toggle()

}
...