Вопрос или проблема
Я пытаюсь создать переход, похожий на matchGeometry, но от представления к .sheet в Swift.
Вот хороший пример этого:
https://x.com/mlaithv/status/1835041850236838265?s=61
Виджет выбора iOS также имеет такой же переход, и это действительно круто!
Нативно это не возможно, но с помощью UIViewControllerTransitioningDelegate вы можете создать пользовательский переход к новому контроллеру представления, изменив функцию animationController делегата.
Если я использую UISheetPresentationController в качестве базового стиля представления для целевого представления (в данном случае sheet), и инициализирую его с упомянутым пользовательским делегатом перехода, я могу добиться эффекта совпадения геометрии, который я ищу, используя технику снимков, упомянутую повсюду здесь на Stack Overflow. Однако я теряю нативные жесты, интерактивность и ощущения от нативного .sheet.
Есть ли способ, как мне можно унаследовать animationController и через него жесты, взаимодействия и т. д. нативного UISheet, а затем как-то расширить/изменить его с эффектом совпадения геометрии?
Ответ или решение
Чтобы реализовать эффект перехода, подобный matchGeometry, от представления к .sheet
, сохранив при этом нативные жесты и интерактивность, вам необходимо создать собственный делегат для анимации перехода, который будет переопределять метод animationController
в UIViewControllerTransitioningDelegate
. Однако вместо того, чтобы полностью создавать новую анимацию, мы можем попробовать наследовать существующий контроллер анимации от UISheetPresentationController
и адаптировать его.
Вот пошаговое руководство по реализации:
-
Создайте кастомный transitioning delegate:
Вам нужно создать класс, который будет реализовыватьUIViewControllerTransitioningDelegate
. Этот класс будет отвечать за создание и возврат вашего аниматора.class CustomTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return MatchGeometryAnimator() } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return MatchGeometryAnimator() } }
-
Создайте аниматор:
Создайте класс, который реализуетUIViewControllerAnimatedTransitioning
. В этом классе сконструируйте вашу кастомную анимацию, используя свойстваtransitionContext
, чтобы получить доступ к виджетам исходного представления и целевого представления.class MatchGeometryAnimator: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.5 // продолжительность анимации } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { // Здесь выполните свою кастомную анимацию let containerView = transitionContext.containerView let toView = transitionContext.view(forKey: .to)! let fromView = transitionContext.view(forKey: .from)! // Добавьте целевое представление на контейнер containerView.addSubview(toView) // Выполните анимацию toView.alpha = 0.0 UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: { toView.alpha = 1.0 }) { finished in transitionContext.completeTransition(finished) } } }
-
Используйте
UISheetPresentationController
:
В вашем исходном представлении инициализируйтеUISheetPresentationController
с вашим кастомным делегатом перехода:let viewControllerToPresent = YourSheetViewController() viewControllerToPresent.modalPresentationStyle = .custom let transitioningDelegate = CustomTransitioningDelegate() viewControllerToPresent.transitioningDelegate = transitioningDelegate // Настройка UISheetPresentationController if let sheet = viewControllerToPresent.sheetPresentationController { sheet.detents = [.medium(), .large()] // Установите другие параметры по желанию } present(viewControllerToPresent, animated: true, completion: nil)
- Сохраните нативную интерактивность:
Чтобы сохранить жесты и интерактивность, убедитесь, что вашUISheetPresentationController
отвечает за обработку жестов. Реализуйте необходимые методы, чтобы поддерживать оригинальную интерактивность, путем использования блоков анимации в вашем кастомном аниматоре.
Эта структура поможет вам достигнуть желаемого эффекта перехода с сохранением нативных жестов и интерактивности. Используя стандартные методы анимации и структурирование, вы сможете адаптировать поведение анимации, сохраняя тот опыт, к которому привыкли пользователи.