Ошибка анимации в iOS 10

Начиная с iOS 10 я заметил, что анимация изменения макета ( layoutIfNeeded() ) не является анимацией. Вот мое расширение UIView, которое отлично работает на iOS 9 и ниже.

func slideIn(from edgeConstraint: NSLayoutConstraint, withDuration duration: Double = 0.25, finishedAnimating: (() -> Void)? = nil) {
    dispatch_async(dispatch_get_main_queue()) {
        edgeConstraint.constant = 0
        UIView.animateWithDuration(duration,
            delay: 0.0,
            options: .BeginFromCurrentState,
            animations: { self.layoutIfNeeded() },
            completion: { didComplete in
                finishedAnimating?()
        })
    }
}

func slideOut(from edgeConstraint: NSLayoutConstraint, withDuration duration: Double = 0.25, finishedAnimating: (() -> Void)? = nil) {
    dispatch_async(dispatch_get_main_queue()) {
        edgeConstraint.constant = -self.frame.height
        UIView.animateWithDuration(duration,
            delay: 0.0,
            options: .BeginFromCurrentState,
            animations: { self.layoutIfNeeded() },
            completion: { didComplete in
                finishedAnimating?()
        })
    }
}

Кто-нибудь знает, почему он не анимируется?


person SeanRobinson159    schedule 16.09.2016    source источник
comment
У вас тоже проблемы на реальном устройстве?   -  person Dan Levy    schedule 17.09.2016
comment
@DanLevy Да iPhone 6S iOS 10.0.1   -  person SeanRobinson159    schedule 17.09.2016
comment
Что ты имеешь в виду под неправильной работой?   -  person Aaron    schedule 17.09.2016
comment
@ Аарон, это не анимация. Вместо того, чтобы скользить из одной точки в другую, он прыгает в конечную точку без какой-либо анимации.   -  person SeanRobinson159    schedule 17.09.2016
comment
Вы используете Swift 3?   -  person Aaron    schedule 17.09.2016
comment
@ Аарон, я использую Swift 2.3.   -  person SeanRobinson159    schedule 17.09.2016
comment
@ Аарон Да, это не сработало.   -  person SeanRobinson159    schedule 17.09.2016


Ответы (1)


В своих блоках анимации вы вызываете self.layoutIfNeeded(), где self — это экземпляр UIView, который вы хотите анимировать. Вызов layoutIfNeeded() перерисовывает представление, к которому вызывается метод, и все, если это подпредставления. В вашем случае вы не хотите перерисовывать UIView, вы хотите перерисовывать супервизор представления.

Ваши функции имели бы смысл и работали правильно, если бы они вызывались в контроллере представления, но поскольку они вызываются в расширении самого UIView, вам нужно вызвать что-то вроде view.superview?.layoutIfNeeded()

person Aaron    schedule 16.09.2016
comment
Так что это сработало. Но почему на iOS 9 это работало без ссылки на супервью, а теперь на iOS 10 надо супервью указывать? - person SeanRobinson159; 17.09.2016
comment
Ошибка должна быть независимой от ОС, поэтому я точно не знаю, почему она будет работать на iOS 9. - person Aaron; 17.09.2016
comment
На самом деле это не зависит от ОС. Раньше это действительно работало на 9 и более старых версиях. Это новое поведение, которое оказалось исправленной ошибкой, ранее было представлено в iOS10 — stackoverflow.com/a/39548367/1045672 — См. примечание к выпуску Apple. - person Teffi; 27.09.2016