Мое приложение имеет два контроллера вида (VC A & B) и пользовательский переход между ними.
При использовании жеста панорамирования влево на VC A интерактивный анимированный переход модально представляет VC B поверх Aскользящий справа (справа налево).Чтобы закрыть VC B, пользователь может:
- Использовать жест панорамирования вправо: запустит интерактивный переход, который сдвинет VC B вправо и откроет VC A. Положение VC B определеноинтерактивно с помощью состояния жеста панорамирования.Взаимодействие «управляется» объектом
UIPercentDrivenInteractiveTransition
. - Используйте кнопку «Закрыть» на панели навигации VC B.Это вызовет пользовательский переход (слайд вправо) без взаимодействия (просто анимированный).
Проблема в том, что тестирование выполняется на Xcode 10 Seed (сборка 10A254a) + iOS 12 Simulator (X или XR или XS)) Я могу легко добраться до состояния, когда пользовательский переход никогда не завершается, а пользовательский интерфейс остается в странном состоянии :
- Пользовательский интерфейс застрял на VC B, и никакие жесты илиработает нажатие.
- Приложение не зависло - я вижу, что журналы conosle все еще работают, и активна сетевая активность (в журнале нет ошибок)
- Приостановить работу приложения в этом застрявшем состоянии я могусм. com.apple.main-thread не застрял.
- Когда я нажимаю «Отладочная иерархия просмотра», происходит что-то странное: на экране sim я все еще вижу VC B и весь пользовательский интерфейс отключен ,На представлении основной вид отладчика - я вижу VC A подпредставления , нарисованные так, как будто переход сделан.На представлении отладчик оставил представление дерева - я вижу иерархию представления VC B .
Эта проблема никогда не возникала ни в какой предыдущей версии Xcode и / или iOS до Xcode 10 /iOS12.
Это мой animateTransition
метод в моем пользовательском UIViewControllerAnimatedTransitioning
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to) else {
transitionContext.completeTransition(false)
return
}
let containterView = transitionContext.containerView
containterView.insertSubview(toVC.view, belowSubview: fromVC.view)
let bounds = fromVC.view.bounds
var xOffsetMultiplier : CGFloat = 0.0
var yOffsetMultiplier : CGFloat = 0.0
switch direction {
case .up:
yOffsetMultiplier = -1.0
case .right:
xOffsetMultiplier = 1.0
case .left:
xOffsetMultiplier = -1.0
case .down:
yOffsetMultiplier = 1.0
}
print(xOffsetMultiplier,bounds.size.width,bounds.size.height )
UIView.animate(withDuration: duration, animations: {
print("animating...")
//fromVC.navigationController?.navigationBar.alpha = 0.0
fromVC.view.frame = fromVC.view.frame.offsetBy(dx: xOffsetMultiplier * bounds.size.width, dy: yOffsetMultiplier * bounds.size.height)
}, completion: { finished in
print("completed animation")
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
//fromVC.navigationController?.navigationBar.alpha = 1.0
})
}
Отпечатки есть только для отладки.
Это последовательность, которая легковоссоздает проблему:
- Используйте жест панорамирования, чтобы начать интерактивный переход от B к A, но никогда не завершайте его - это вызовет
cancel()
для объекта UIPercentDrivenInteractiveTransition
+ Я могу убедиться, что анимация завершена, - Нажмите кнопку «Закрыть», чтобы вызвать неинтерактивный переход для отмены B. B никогда не удаляется, а пользовательская анимация никогда не завершается!
На устройстве, которое я не смог воссоздатьэта проблема вообще (пока) - и все переходы работают как положено.