swift - 使用平移手势的交互式 viewController

标签 swift

大家,我一直在努力寻找交互式 View Controller 转换的解决方案,在该转换中,您可以使用向下的平移手势将全屏 View Controller 从顶部带到底部。有没有人遇到过或创建过这样的代码。下面是我的代码。我已经按下了关闭手势,但无法弄清楚如何通过在屏幕上向下滑动来呈现 View Controller 。请帮忙!!!

 import UIKit    
 class ViewController: UIViewController {

let interactor = Interactor()
   var interactors:Interactor? = nil
    let Mview = ModalViewController()
let mViewT: ModalViewController?  = nil
var presentedViewControllers: UIViewController?

override func viewDidLoad() {
    Mview.transitioningDelegate = self
    Mview.modalPresentationStyle = .FullScreen
}

   @IBAction func cameraSlide(sender: UIPanGestureRecognizer) {



    let percentThreshold:CGFloat = 0.3

    // convert y-position to downward pull progress (percentage)
    let translation = sender.translationInView(Mview.view)
    let verticalMovement = translation.y / UIScreen.mainScreen().bounds.height
    let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
    let downwardMovementPercent = fminf(downwardMovement, 1.0)
    let progress = CGFloat(downwardMovementPercent)

    guard let interactor = interactors else { return }

    switch sender.state {
    case .Began:

        interactor.hasStarted = true
        self.presentViewController(Mview, animated: true, completion: nil)
    case .Changed:
        interactor.shouldFinish = progress > percentThreshold
        interactor.updateInteractiveTransition(progress)
    case .Cancelled:
        interactor.hasStarted = false
        interactor.cancelInteractiveTransition()
    case .Ended:
        interactor.hasStarted = false
        if !interactor.shouldFinish {
            interactor.cancelInteractiveTransition()
        } else {
            interactor.finishInteractiveTransition()
        }        default:
        break
    }
}

}

扩展ViewController:UIViewControllerTransitioningDelegate { func AnimationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 返回 DismissAnimator() }

func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
    return interactor.hasStarted ? interactor : nil
}

func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return PresentAnimator()
}
func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
    return interactor.hasStarted ? interactor : nil
}

}

  class PresentAnimator: NSObject {

}

扩展 PresentAnimator:UIViewControllerAnimatedTransitioning { func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { 返回1.0 }

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    guard

        let fromVC2 = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
    let toVC2 = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey),
        let containerView2 = transitionContext.containerView() else {return}

    let initialFrame = transitionContext.initialFrameForViewController(fromVC2)
    toVC2.view.frame = initialFrame
    toVC2.view.frame.origin.y = -initialFrame.height * 2


    containerView2.addSubview(fromVC2.view)
    containerView2.addSubview(toVC2.view)

    let screenbounds = UIScreen.mainScreen().bounds
    let Stage = CGPoint(x: 0, y: 0)
    let finalFrame = CGRect(origin: Stage, size: screenbounds.size)

    UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
        toVC2.view.frame = finalFrame
        }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
    }
    )



}

}

   class ModalViewController: UIViewController {

let interactors = Interactor()
var interactor:Interactor? = nil

@IBAction func close(sender: UIButton) {
    dismissViewControllerAnimated(true, completion: nil)
}




@IBAction func handleGesture(sender: UIPanGestureRecognizer) {

    let percentThreshold:CGFloat = 0.3

    // convert y-position to downward pull progress (percentage)
    let translation = sender.translationInView(self.view)
    let verticalMovement = translation.y / -view.bounds.height * 2
    let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
    let downwardMovementPercent = fminf(downwardMovement, 1.0)
    let progress = CGFloat(downwardMovementPercent)

    guard let interactor = interactor else { return }

    switch sender.state {
    case .Began:
        interactor.hasStarted = true
        dismissViewControllerAnimated(true, completion: nil)
    case .Changed:
        interactor.shouldFinish = progress > percentThreshold
        interactor.updateInteractiveTransition(progress)
    case .Cancelled:
        interactor.hasStarted = false
        interactor.cancelInteractiveTransition()
    case .Ended:
        interactor.hasStarted = false
        if !interactor.shouldFinish {
            interactor.cancelInteractiveTransition()
        } else {
            interactor.finishInteractiveTransition()
        }        default:
        break
    }
}

}

    import UIKit

类 DismissAnimator: NSObject { }

扩展 DismissAnimator : UIViewControllerAnimatedTransitioning { func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { 返回1.0 }

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    guard
        let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
        let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey),
        let containerView = transitionContext.containerView()
        else {
            return
    }

    containerView.insertSubview(toVC.view, belowSubview: fromVC.view)

    let screenBounds = UIScreen.mainScreen().bounds
    let topLeftCorner = CGPoint(x: 0, y: -screenBounds.height * 2)
    let finalFrame = CGRect(origin: topLeftCorner, size: screenBounds.size)

    UIView.animateWithDuration(
        transitionDuration(transitionContext),animations: {fromVC.view.frame = finalFrame},
        completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
        }
    )

       }

}

最佳答案

如果您想要一个简单的平移手势在 UIViewController 之间切换,您可以查看以下内容:

http://www.appcoda.com/custom-segue-animations/

如果您希望它具有交互性,例如您可以在 VC 之间来回切换而不必完成整个转换,我建议您查看以下内容:

https://www.youtube.com/watch?v=3jAlg5BnYUU

如果您想更进一步并拥有自定义的关闭动画,那么只需看看这个:

https://www.raywenderlich.com/110536/custom-uiviewcontroller-transitions

关于swift - 使用平移手势的交互式 viewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37902579/

相关文章:

ios - 在 swift 中在矩形上绘制渐变

iphone - Fidget Spinner 动画 Swift?

ios - 以编程方式关闭 iOS 屏幕

ios - SIGVART 与单元 View 与标签

ios - Swift Playground - "Use of unresolved identifier ' myClass'"但仍然可以编译

ios - 用字典数据填充 UITableView (Swift)

swift - 仅类协议(protocol)作为具有 AnyObject 约束的关联类型的类型别名

ios - 在 ViewDidLoad 中执行 Segue

ios - 设置 delegate = self 导致线程 1 : exc_bad_instruction (code=exc_i386_invop subcode=0x0)

ios - OAuthSwift WKWebView 不断循环打开和关闭