1

我有一个CustomPresentationController它使用自定义动画进行动画和动画;iOS - 关闭显示视图控制器触及其​​外部视图

这个特定的控制器会在屏幕尺寸的50%处显示出来,而当我呈现它时,我会在presentingViewController上添加一个阴影灰色视图,以便增加一些深度。

我只能驳回presentedViewController如果我在NavBar我称之为默认dismiss(:)方法挖掘cancel按钮。

我试图做到的是检测水龙头presentedViewController外面,也许是灰色地带里面,这样我就可以关闭该presentedViewController,不知何故像解雇一名ActionSheet,但我没能做到这一点。让我解释我到目前为止所尝试的。

我试图将UITapGestureRecognizer添加到阴影灰色视图,但由于我呈现的是不同的控制器,所以应用程序引擎可能会认为由于阴影视图不在顶层视图中,因此可能无法访问所以它会阻止识别器 - 每当我点击它时,手势手柄都不会触发。

我现在正在执行另外一个向下滑动来解散,我可以很容易地做到这一点,但我真的希望水龙头外部功能也可以工作。

任何暗示我该如何解决这个问题?

该应用的图片如下:

screenshot

回答

1

我只是不得不在我的应用程序之一实现这一点。

我通过添加一个覆盖整个视图和此按钮的按钮,一旦点击触发VC就被解雇了。

一旦添加按钮,您可以添加您的自定义视图顶部。

到目前为止,它看起来像工作得很好。

我下面的代码(我做的一切程序,没有故事板)

//————————————————————————————— 
    // MARK: View Life Cycle 
    //————————————————————————————— 

override func viewDidLoad() { 
    super.viewDidLoad() 
    view.backgroundColor = UIColor.clear //VC view background transparent 
    setupUI() 
} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    //Animate blackView opacity to 1 to give some depth 
    UIView.animate(withDuration: 0.4, delay: 0.2, options: .curveEaseInOut, animations: { 
     self.blackView.alpha = 1 
    }) 
} 

    //———————————————— 
    // MARK: Setup UI 
    //———————————————— 

    let blackView: UIView = { 
     let view = UIView() 
     view.alpha = 0.0 
     view.backgroundColor = UIColor.black.withAlphaComponent(0.6) 
     return view 
    }() 
    //Invisible button which covers the entire view that can be tapped 
    lazy var dismissLayerBtn: UIButton = { 
     let btn = UIButton() 
     btn.addTarget(self, action: #selector(tapToDismiss), for: .touchUpInside) 
     return btn 
    }() 

    @objc func tapToDismiss() { 
     print("tapToDimiss") 
     self.dismiss(animated: true, completion: nil) 
    } 

    let milestonePickerView: MilestonePickerView = { 
     let view = MilestonePickerView(frame: .zero) 
     return view 
    }() 

    func setupUI() { 

     view.addSubview(blackView) 
     view.addSubview(dismissLayerBtn) 
     view.addSubview(milestonePickerView) //Important to add the customView after the button. 

     blackView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0) 

     dismissLayerBtn.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0) 

     milestonePickerView.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 40, paddingRight: 20, width: 0, height: 400) 

//I'm using a custom extension to setup constraints (anchors) 
    } 

如果你使用的故事板,请确保你把隐形按钮自定义视图下。

我希望这会有所帮助。

1

你在正确的轨道与UITapGestureRecognizer上。只要确保你实施shouldRecognizeSimultaneouslyWith这样:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 
    return true 
} 

这应该允许手势正确触发。

+0

嗯......我从来没有使用过这个属性,这可能是我为什么无法弄清楚的原因:D 我会尝试一下,我会反馈你 –

+0

它没有用。以某种方式设置该属性,手势识别器不会触发。 它可能认为该视图对用户不可用,因为它不在顶层视图层次结构中。 应该有办法在屏幕上的任何位置检测触摸,而不管呈现的视图如何,然后检查触摸位置是否高于弹出窗口,然后我知道何时解雇 –

0

试着用我下面的代码:

你需要实现这个方法里面,你呈现控制器,您使用作为一个弹出工作。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    // Here write down you logic to dismiss controller  
} 

希望这会起作用。 :D

+0

这没有奏效。 由于我的弹出视图的类型为'UICollectionView',我必须设置'collectionView?.isUserInteractionEnabled = false'来检测它内部的触摸,但即使它检测到触摸,它也不会检测触摸是否在阴影中。 如果我触摸阴影区域,它不会触发'touches(:)'方法 –

相关问题