我正在使用UIViewControllerAnimatedTransitioning呈现自定义viewController过渡动画。
当前设置是触摸ViewController按钮,然后显示NextViewController。
我的动画以模态方式呈现NextViewController,尽管视图从底部向上滑动以覆盖上一个ViewController的四分之三,如下所示。
我可以关闭此呈现的视图,只需触摸我的一个连接按钮即可。我想要实现的是,当触摸了透明的黑暗区域时,我可以关闭显示的NextViewController。
唯一的问题是,暗区不是所提供的viewController的一部分,而是所呈现的viewController的一部分,并且不会调用touch事件。在该区域中处理触摸事件的正确方法是什么?从哪个VC有代码来处理它?</ p>
如果需要了解我的逻辑,请在这里放置我的UIViewControllerAnimatedTransitioning对象。
class ModalSheetTransitioning: NSObject, UIViewControllerAnimatedTransitioning {
// MARK: - Internal
let destinationMinYDivisor = CGFloat(5)
let downChevronXDiviser = CGFloat(2)
let animationSpringOptions = CGFloat(0.8)
// MARK: - Properties
var animationDuration: Double
var destinationCornerRadius: CGFloat
var presenting: Bool
var chevronDownImageView = UIImageView()
// MARK: - Init
init(animationDuration: Double? = 0.6, destinationCornerRadius: CGFloat? = 8.0, presenting: Bool? = true) {
self.animationDuration = animationDuration!
self.destinationCornerRadius = destinationCornerRadius!
self.presenting = presenting!
}
// MARK: - UIViewControllerAnimatedTransitioning delegate
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return self.animationDuration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let toView = transitionContext.view(forKey: .to) else { return }
guard let fromView = transitionContext.view(forKey: .from) else { return }
var finalFrame = CGRect()
if presenting {
containerView.addSubview(toView)
toView.alpha = 0.0
toView.frame.y = (fromView.frame.maxY)
finalFrame = CGRect(0, (toView.frame.height) / (self.destinationMinYDivisor), (toView.frame.width), (toView.frame.height) - ((toView.frame.height) / (self.destinationMinYDivisor)))
} else {
finalFrame = CGRect(0, (toView.frame.maxY), (toView.frame.width), (toView.frame.height) - ((toView.frame.height) / (self.destinationMinYDivisor)))
}
UIView.animate(withDuration: self.animationDuration,
delay: 0.0,
usingSpringWithDamping: animationSpringOptions,
initialSpringVelocity: animationSpringOptions,
animations: {
toView.alpha = 1.0
if self.presenting {
toView.frame = finalFrame
} else {
fromView.frame = finalFrame
}
}, completion: { _ in
transitionContext.completeTransition(true)
// Re-add fromView to UIWindow as this gets completely removed by completeTransition!
guard let window = UIApplication.shared.keyWindow else { return }
if self.presenting {
window.insertSubview(fromView, at: 0)
}
})
}
}
以及我如何遵守此协议。
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
presenting.view.layer.opacity = 1.0
UIView.animate(withDuration: 1.0, animations: {
presenting.view.layer.opacity = 0.2
})
return ModalSheetTransitioning(animationDuration: 1.0)
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return ModalSheetTransitioning(presenting: false)
}
}
我像下面这样设置代表。
@IBAction func showNextView(_ sender: UIButton) {
let nextViewController = storyboard?.instantiateViewController(withIdentifier: "next")
let navigationController = UINavigationController(rootViewController: nextViewController!)
navigationController.isNavigationBarHidden = true
navigationController.transitioningDelegate = self
self.navigationController?.present(navigationController, animated: true, completion: nil)
}
所以只需要了解我将能够在哪里以及如何触摸暗区域以消除视图,而不是那些按钮之一?