通过点击视图控制器外部关闭部分显示的模态视图控制器
Close partially shown modal view controller by tapping outside of the view controller
我使用 UIViewControllerAnimatedTransitioning 进行了自定义模式转换。转换完成后,模态显示的视图控制器填充父视图的一部分,父视图控制器的某些部分仍然可见。
我需要知道如何检测显示的视图控制器外部的点击(或部分显示的父视图控制器),以便我可以使用它来关闭模式。我了解如何向视图添加手势,但找不到要向哪个视图添加手势。
我查看了 Whosebug,但没有专门针对自定义模式转换的示例。
这是自定义转换的代码
class PartialSlideInAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
var direction: SlideAnimationDirectionStyle
var duration: TimeInterval = 0.125
var presentedControllerWidth: CGFloat = 250
let fadeAlpha: CGFloat = 0.5
init(direction: SlideAnimationDirectionStyle) {
self.direction = direction
super.init()
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return TimeInterval(duration)
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
// Setup Views
guard let presentedFromVC = transitionContext.viewController(forKey: .from) else {transitionContext.completeTransition(false); return }
guard let presentingToVC = transitionContext.viewController(forKey: .to) else {transitionContext.completeTransition(false); return }
let contrainerView = transitionContext.containerView // アニメーションはこのViewで行われる、アニメーションを実装する presenter, presenteeをこの上に載せないとアニメーションが動かない
// Setup Frames
let positionHidden = CGRect(x: contrainerView.frame.width + 1, y: 0, width: presentedControllerWidth, height: contrainerView.frame.height)
let positionShown = CGRect(x: contrainerView.frame.width - presentedControllerWidth, y: 0, width: presentedControllerWidth, height: contrainerView.frame.height)
switch direction {
case .slideIn:
contrainerView.addSubview(presentingToVC.view)
presentingToVC.view.frame = positionHidden
UIView.animate(withDuration: duration, animations: {
presentingToVC.view.frame = positionShown
presentedFromVC.view.alpha = self.fadeAlpha
}, completion: { success in
transitionContext.completeTransition( success )
})
case .slideOut:
contrainerView.addSubview(presentedFromVC.view)
presentedFromVC.view.frame = positionShown
UIView.animate(withDuration: duration, animations: {
presentedFromVC.view.frame = positionHidden
presentingToVC.view.alpha = 1.0
}, completion: { success in
transitionContext.completeTransition( success )
})
}
}
}
您尝试过使用 UIGestureRecognizer
了吗? UIGestureRecognizer 可用于识别子视图控制器和父视图控制器内的点击事件。对于 swift 3,UIRecognizerDelegate
应该有一个 handleTapBehind
函数,它应该允许您执行您要查找的操作。
查看是否记录了什么 here
请参阅链接 post 中的 "Swift 3.1 solution that works in both portrait and landscape"。
我使用 UIViewControllerAnimatedTransitioning 进行了自定义模式转换。转换完成后,模态显示的视图控制器填充父视图的一部分,父视图控制器的某些部分仍然可见。
我需要知道如何检测显示的视图控制器外部的点击(或部分显示的父视图控制器),以便我可以使用它来关闭模式。我了解如何向视图添加手势,但找不到要向哪个视图添加手势。
我查看了 Whosebug,但没有专门针对自定义模式转换的示例。
这是自定义转换的代码
class PartialSlideInAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
var direction: SlideAnimationDirectionStyle
var duration: TimeInterval = 0.125
var presentedControllerWidth: CGFloat = 250
let fadeAlpha: CGFloat = 0.5
init(direction: SlideAnimationDirectionStyle) {
self.direction = direction
super.init()
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return TimeInterval(duration)
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
// Setup Views
guard let presentedFromVC = transitionContext.viewController(forKey: .from) else {transitionContext.completeTransition(false); return }
guard let presentingToVC = transitionContext.viewController(forKey: .to) else {transitionContext.completeTransition(false); return }
let contrainerView = transitionContext.containerView // アニメーションはこのViewで行われる、アニメーションを実装する presenter, presenteeをこの上に載せないとアニメーションが動かない
// Setup Frames
let positionHidden = CGRect(x: contrainerView.frame.width + 1, y: 0, width: presentedControllerWidth, height: contrainerView.frame.height)
let positionShown = CGRect(x: contrainerView.frame.width - presentedControllerWidth, y: 0, width: presentedControllerWidth, height: contrainerView.frame.height)
switch direction {
case .slideIn:
contrainerView.addSubview(presentingToVC.view)
presentingToVC.view.frame = positionHidden
UIView.animate(withDuration: duration, animations: {
presentingToVC.view.frame = positionShown
presentedFromVC.view.alpha = self.fadeAlpha
}, completion: { success in
transitionContext.completeTransition( success )
})
case .slideOut:
contrainerView.addSubview(presentedFromVC.view)
presentedFromVC.view.frame = positionShown
UIView.animate(withDuration: duration, animations: {
presentedFromVC.view.frame = positionHidden
presentingToVC.view.alpha = 1.0
}, completion: { success in
transitionContext.completeTransition( success )
})
}
}
}
您尝试过使用 UIGestureRecognizer
了吗? UIGestureRecognizer 可用于识别子视图控制器和父视图控制器内的点击事件。对于 swift 3,UIRecognizerDelegate
应该有一个 handleTapBehind
函数,它应该允许您执行您要查找的操作。
查看是否记录了什么 here
请参阅链接 post 中的 "Swift 3.1 solution that works in both portrait and landscape"。