PullToDismissTransition
注意: 这还是一个测试版本!我们欢迎 pull requests。
使用 UIPercentDrivenInteractiveTransition
和 UIViewControllerAnimatedTransitioning
来快速实现漂亮的“拉动以 dismiss”交互,应用于模态视图控制器。 — 此版本也可以动态地处理 UIScrollView
的弹跳切换功能。
打包的过渡类型
存在 3 种打包的过渡类型
slideStatic
= 默认,垂直滑动离开,通过平移手势。slideDynamic
= 与slideStatic
相同,但不截图视图控制器。scale
= 在最终淡出并淡入下方的视图之前缩小视图。
所有过渡类型都配置为尽可能减少对 UIScrollView
垂直“弹跳”的干扰。
示例
“滑动”过渡示例,在单个连续手势中实现对 UIScrollView
的反应
安装
PullToDismissTransition
通过 CocoaPods 提供。要安装它,只需在 Podfile 中添加以下行
pod "PullToDismissTransition"
说明
当展示您的模态视图控制器时,请确保设置呈现上下文,否则过渡效果将不会在其他视图控制器之上显示
var viewController = MyAwesomeViewController()
viewController.isPullToDismissEnabled = true
viewController.modalPresentationCapturesStatusBarAppearance = true
viewController.modalPresentationStyle = .overFullScreen
self.present(viewController, animated: true)
最简单的实现方式是,在您的视图控制器上采用 PullToDismissable
协议
import PullToDismissTransition
import UIKit
class MyAwesomeViewController: UIViewController, PullToDismissable {
private(set) lazy var pullToDismissTransition: PullToDismissTransition = {
let pullToDismissTransition = PullToDismissTransition(
viewController: self,
transitionType: .slideStatic
)
////
// NOTE: Optional, unless you implement any of the delegate methods:
pullToDismissTransition.delegate = self
return pullToDismissTransition
}()
override func didMove(toParentViewController parent: UIViewController?) {
super.didMove(toParentViewController: parent)
setupPullToDismiss()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setupPullToDismiss()
////
// NOTE: Optional, unless you've navigated to a scroll-view within a navigation
// flow (but the same context), and therefore must toggle monitoring to it:
pullToDismissTransition.monitorActiveScrollView(scrollView: scrollView)
}
}
extension MyAwesomeViewController: UIViewControllerTransitioningDelegate {
func animationController(forDismissed dismissed: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
guard isPullToDismissEnabled else { return nil }
return pullToDismissTransition
}
func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning)
-> UIViewControllerInteractiveTransitioning? {
guard isPullToDismissEnabled else { return nil }
return pullToDismissTransition
}
}
... 嗯哼!
使用 setPullToDismissEnabled()
方法可以恢复 iOS 的默认过渡效果,例如通过按钮点击来关闭。您还可以在 viewDidLoad()
中调用此方法以启用,如果您在初始化时没有设置 "isPullToDismissEnabled"。
PullToDismissTransitionDelegate
方法
为了获得更多控制,您可以可选地实现 PullToDismissTransition
的代理
extension MyAwesomeViewController: PullToDismissTransitionDelegate {
func canBeginPullToDismiss(on dismissingViewController: UIViewController) -> Bool {
// Return "false" to disable the transition during certain events, such as a horizontal
// page-swipe.
return true
}
func didBeginPullToDismissAttempt(on dismissingViewController: UIViewController) {
guard dismissingViewController === self else { return }
// Handle events when the transition becomes active, such as adjusting or disabling certain GUI.
}
func didCompletePullToDismissAttempt(on dismissingViewController: UIViewController, willDismiss: Bool) {
guard dismissingViewController === self else { return }
// Called when the attempt is cancelled or completed.
// Handle events when the transition becomes active, such as reverting adjusted or re-enabling
// certain GUI.
}
func didFinishTransition(for dismissingViewController: UIViewController, didDismiss: Bool) {
guard dismissingViewController === self else { return }
// Called after the transition completes.
}
}
在您的实现中,不需要这些方法,但它们是可用的,以防您需要。
UIScrollView
兼容性
PullToDismissTransition
是为与 UIScrollView
一起使用而设计的,并提供最小的垂直弹跳干扰。然而,当在相同上下文中切换视图控制器时(例如,在 UINavigationController
中的视图控制器之间导航时),您需要确保过渡与屏幕上显示的任何活动滚动视图保持最新
pullToDismissTransition.monitorActiveScrollView(scrollView: myAwesomeScrollView)
调用此方法将替代任何现有监听器,并且也应用于其他滚动视图后裔,如 UITableView
、UICollectionView
等。
UINavigationController
与 PullToDismissable
协议的兼容性
PullToDismissable
协议是为 UINavigationController
的 子 视图控制器而设计的,因为导航流程中的视图可能具有需要通过过渡的 monitorActiveScrollView(scrollView: UIScrollView)
方法进行监控的滚动/弹跳行为。
PullToDismissTransition
另一种直接实现 虽然提供了 PullToDismissable
协议以方便您且减少复用时的代码复杂性,但也可以直接通过引用此协议的代码来实现 PullToDismissTransition
的集成。
作者
Ben Guild, [email protected]
许可协议
PullToDismissTransition
在 MIT 许可协议下可用。有关更多信息,请参阅 LICENSE 文件。