PullToDismissTransition 0.7.10

PullToDismissTransition 0.7.10

benguild 维护。



PullToDismissTransition

注意: 这还是一个测试版本!我们欢迎 pull requests。

使用 UIPercentDrivenInteractiveTransitionUIViewControllerAnimatedTransitioning 来快速实现漂亮的“拉动以 dismiss”交互,应用于模态视图控制器。 — 此版本也可以动态地处理 UIScrollView 的弹跳切换功能。

Version License Platform

打包的过渡类型

存在 3 种打包的过渡类型

  • slideStatic = 默认,垂直滑动离开,通过平移手势。
  • slideDynamic = 与 slideStatic 相同,但不截图视图控制器。
  • scale = 在最终淡出并淡入下方的视图之前缩小视图。

所有过渡类型都配置为尽可能减少对 UIScrollView 垂直“弹跳”的干扰。

示例

“滑动”过渡示例,在单个连续手势中实现对 UIScrollView 的反应

Example of the “slide” transition reversing against a UIScrollView in a single, fluid gesture

安装

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)

调用此方法将替代任何现有监听器,并且也应用于其他滚动视图后裔,如 UITableViewUICollectionView 等。

UINavigationControllerPullToDismissable 协议的兼容性

PullToDismissable 协议是为 UINavigationController 视图控制器而设计的,因为导航流程中的视图可能具有需要通过过渡的 monitorActiveScrollView(scrollView: UIScrollView) 方法进行监控的滚动/弹跳行为。

另一种直接实现 PullToDismissTransition

虽然提供了 PullToDismissable 协议以方便您且减少复用时的代码复杂性,但也可以直接通过引用此协议的代码来实现 PullToDismissTransition 的集成。

作者

Ben Guild, [email protected]

许可协议

PullToDismissTransition 在 MIT 许可协议下可用。有关更多信息,请参阅 LICENSE 文件。