gpt4 book ai didi

ios - 在 iOS 中,如何向下拖动以关闭模态?

转载 作者:IT王子 更新时间:2023-10-29 07:31:20 25 4
gpt4 key购买 nike

关闭模态框的一种常见方法是向下滑动 - 我们如何允许用户向下拖动模态框,如果它足够远,模态框将被关闭,否则它会动画回到原始位置?

例如,我们可以在 Twitter 应用的照片浏览或 Snapchat 的“发现”模式中找到它。

类似的线程指出,我们可以使用 UISwipeGestureRecognizer 和 [self dismissViewControllerAnimated...] 在用户向下滑动时关闭模态 VC。但这只处理单次滑动,不允许用户拖动模式。

最佳答案

我刚刚创建了一个教程,用于交互式地向下拖动模态以将其关闭。

http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/

一开始我发现这个主题令人困惑,所以本教程逐步构建了这个主题。

enter image description here

如果你只是想自己运行代码,这是 repo:

https://github.com/ThornTechPublic/InteractiveModal

这是我使用的方法:

View Controller

您可以使用自定义动画覆盖关闭动画。如果用户正在拖动模式,interactor 就会启动。

import UIKit

class ViewController: UIViewController {
let interactor = Interactor()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let destinationViewController = segue.destinationViewController as? ModalViewController {
destinationViewController.transitioningDelegate = self
destinationViewController.interactor = interactor
}
}
}

extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
DismissAnimator()
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
interactor.hasStarted ? interactor : .none
}
}

解雇动画师

您创建一个自定义动画师。这是一个自定义动画,您将其打包在 UIViewControllerAnimatedTransitioning 协议(protocol)中。

import UIKit

class DismissAnimator : NSObject {
let transitionDuration = 0.6
}

extension DismissAnimator : UIViewControllerAnimatedTransitioning {
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
transitionDuration
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
guard
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey),
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey),
let containerView = transitionContext.containerView()
else {
return
}
if transitionContext.transitionWasCancelled {
containerView.insertSubview(toVC.view, belowSubview: fromVC.view)
}
let screenBounds = UIScreen.mainScreen().bounds
let bottomLeftCorner = CGPoint(x: 0, y: screenBounds.height)
let finalFrame = CGRect(origin: bottomLeftCorner, size: screenBounds.size)

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

交互器

您将 UIPercentDrivenInteractiveTransition 子类化,以便它可以充当您的状态机。由于两个 VC 都访问交互器对象,因此使用它来跟踪平移进度。

import UIKit

class Interactor: UIPercentDrivenInteractiveTransition {
var hasStarted = false
var shouldFinish = false
}

模态视图 Controller

这将平移手势状态映射到交互器方法调用。 translationInView() y 值确定用户是否超过阈值。当平移手势为 .Ended 时,交互器完成或取消。

import UIKit

class ModalViewController: UIViewController {

var interactor:Interactor? = nil

@IBAction func close(sender: UIButton) {
dismiss(animated: true)
}

@IBAction func handleGesture(sender: UIPanGestureRecognizer) {
let percentThreshold:CGFloat = 0.3

let translation = sender.translation(in: view)
let verticalMovement = translation.y / view.bounds.height
let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
let downwardMovementPercent = fminf(downwardMovement, 1.0)
let progress = CGFloat(downwardMovementPercent)
guard interactor = interactor else { return }

switch sender.state {
case .began:
interactor.hasStarted = true
dismiss(animated: true)
case .changed:
interactor.shouldFinish = progress > percentThreshold
interactor.update(progress)
case .cancelled:
interactor.hasStarted = false
interactor.cancel()
case .ended:
interactor.hasStarted = false
interactor.shouldFinish ? interactor.finish() :
interactor.cancel()
default:
break
}
}

}

关于ios - 在 iOS 中,如何向下拖动以关闭模态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29290313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com