创建不占用全屏的 UIViewController 时,如何通过在外部点击来关闭它?

Posted

技术标签:

【中文标题】创建不占用全屏的 UIViewController 时,如何通过在外部点击来关闭它?【英文标题】:When creating a UIViewController that doesn't take up the full screen, how do I dismiss it by tapping outside? 【发布时间】:2015-04-02 22:44:22 【问题描述】:

我正在关注this tutorial 制作覆盖视图控制器,在 ios 8 中使用 frameOfPresentedViewInContainerView,但我很好奇,我将如何根据在可见区域之外的点击来关闭此视图控制器?

【问题讨论】:

【参考方案1】:

There is one popular solution where you add a UITapGestureRecognizer to the window and then perform a hit test to check if the tap was outside the modal view frame.

但是,由于您使用 UIPresentationController,我建议您选择更通用的解决方案:

在你的 UIPresentationController 子类中重写 presentationTransitionWillBegin

override func presentationTransitionWillBegin() 
    var dimView = UIView() // Use your specific subclass here
    dimView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5) // No need for this if you have your subclass defined in IB

    self.containerView?.addSubview(dimView)
    dimView.snp_makeConstraints  (make) -> Void in // I use SnapKit to avoid the NSLayoutConstraint nonsense
        make.edges.equalTo(self.containerView!)
    
    dimView.addSubview(self.presentedViewController.view)

    let transitionCoordinator = self.presentedViewController.transitionCoordinator()

    dimView.alpha = 0
    transitionCoordinator?.animateAlongsideTransition( (context) -> Void in
        dimView.alpha = 1
    , completion:  (context) -> Void in

        )
    

这将为您提供一个适当的调光视图,该视图将放置在您呈现的视图控制器后面。现在完全取决于您如何使用该调光视图,您可以为其设置样式或在其中放置按钮:

我建议在界面构建器中定义这个视图,这样会更容易,示例可能如下所示:

class MyDimView: UIView 
    var onPrevAction: (() -> ())?
    var onNextAction: (() -> ())?
    var onTapAction: (() -> ())?

    @IBOutlet private var prevButton: UIButton!
    @IBOutlet private var nextButton: UIButton!
    @IBOutlet private var button: UIButton!

    @IBAction private func onPrevButtonTouched() 
        if let prevAction = self.onPrevAction 
            prevAction()
        
    

    @IBAction private func onNextButtonTouched() 
        if let nextAction = self.onNextAction 
            nextAction()
        
    

    @IBAction private func onViewTouched() 
        if let tapAction = self.onTapAction 
            tapAction()
        
    

这样您就可以完全控制外部或您呈现的视图控制器发生的事情。

【讨论】:

以上是关于创建不占用全屏的 UIViewController 时,如何通过在外部点击来关闭它?的主要内容,如果未能解决你的问题,请参考以下文章

非全屏和全屏 UIViewController 之间的漂亮幻灯片过渡

iOS 11 实现App在禁止转屏的状态下网页播放器全屏

PresentViewController 一个带有 UINavigationController 的非全屏 UIViewController

css 如何让图片全屏的问题

全屏 UIViewController 的 StatusBarStyle

C#在winform上画一张大于全屏的图片(至少3000*3000像素)。在窗口最大化下用鼠标拖动图片,必须画面流畅。