Пользовательский переход UIViewController застрял на iOS13
Я реализовал настраиваемый переход между двумя контроллерами представления в моем приложении для iOS, и он отлично работал с iOS 10, 11 и 12.
Теперь я хочу подготовить его для iOS 13, используя Xcode 11 beta 6 и iOS 13 beta 8, но переход застрял.
Пользовательский переход должен перемещать первый контроллер представления вверх и за пределы экрана, а второй - снизу вверх. Но теперь он возвращается к стилю представления по умолчанию iOS13.pageSheet
, просто немного уменьшает первый контроллер представления и добавляет затемненное наложение. Но второй вид не появляется.
Я обнаружил, что в методе animatePresentation(context: UIViewControllerContextTransitioning)
в context
не возвращает представление "из", поэтому context.view(forKey: .from)
возвращается nil
.
Что я должен делать без обзора?
FlyUpTransition.swift
class FlyUpTransition: NSObject, UIViewControllerAnimatedTransitioning {
var mode: Mode = .present
enum Mode {
case present
case dismiss
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return TimeInterval(0.45)
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
switch mode {
case .present:
animatePresentation(context: transitionContext)
case .dismiss:
animateDismissal(context: transitionContext)
}
}
func animatePresentation(context: UIViewControllerContextTransitioning) {
guard let fromView = context.view(forKey: .from), let toView = context.view(forKey: .to) else { return }
...
}
func animateDismissal(context: UIViewControllerContextTransitioning) {
guard let fromView = context.view(forKey: .from), let toView = context.view(forKey: .to) else { return }
...
}
}
4 ответа
Хорошо, это было легко, хотя это ломающее изменение API Apple.
viewController.modalPresentationStyle = .fullScreen
Теперь мне нужно просмотреть весь свой проект и проверить все модальные презентации, если они по-прежнему выглядят так, как мне нужно.
TL;DR
Это ошибка iOS, но вы можете использовать context.viewController(forKey:.from).view
как обходной путь.
Полная информация
Похоже, это ошибка в iOS 13.0. Что касается iOS 13.1 beta 3, она все еще там. http://www.openradar.me/radar?id=4999313432248320
Контекст перехода view(forKey:)
метод неправильно возвращает nil при определенных обстоятельствах. Похоже, это происходит дляview(forKey: .from)
когда представляющий контроллер представления представлен в немодальном режиме. При отклонении контроллера представления, который был первоначально представлен из немодального контроллера представления, результатview(forKey: .to)
также равно нулю.
Я наблюдал это не только в новой презентации в виде листов на iPhone, но и в обычных листах и всплывающих окнах на iPad.
Еще одним проявлением этой проблемы, похоже, является то, что finalFrame(for:)
метод возвращает неверный CGRect
когда его спросили, каким должен быть последний кадр для этого контроллера представления. В моем тестировании он возвращает полноэкранный прямоугольник, хотя правильный вид меньше.
Обходной путь - использовать корневой контроллер представления контроллера представления, возвращенный viewController(forKey:)
, хотя документация явно не рекомендует, чтобы: "Представление, возвращаемое этим методом, может быть или не быть корневым представлением соответствующего контроллера представления".
Приведенный выше ответ подходит для установки modalPresentationStyle
к .fullScreen
, однако также стоит упомянуть, что если ваш контроллер представления встроен в UINavigationController
, вам необходимо установить его на контроллере навигации:
navigationController.modalPresentationStyle = .fullScreen
Я установил переход в IB путем перетаскивания из коллекции VC в другую VC, которая используется для отображения деталей.
У меня есть новые открытия по этой проблеме. Чтобы сослаться на toView и fromView, работают оба следующих метода.
Косвенно:
transitionContext.viewController(forKey: .to)?.view
transitionContext.viewController(forKey: .from)?.view
Прямо способом:
transitionContext.view(forKey: .to)
transitionContext.view(forKey: .from)
Но когда я переключил стиль перехода на "Over Full Screen", прямой способ вернуть "nil" как для "toView", так и для "fromView" и работать только косвенно.
Надеюсь, это будет полезно кому-то в будущем.
PS Это мое открытие на моем пути к решению другой проблемы, которая может быть полезна, если вы также столкнулись с проблемой, что "рабочий аниматор" перестает работать в iOS 13 и выше.