当 dismissButton 在 presentableView 之外时,如何使它可点击?

问题描述 投票:0回答:0

我创建了一个自定义的 UIPresentationController,并希望屏幕的前六分之一包含一个 dismissButton 和 dimmingView,分别在呈现和关闭时淡入和淡出。但是,因为 dismissButton 在 presentedView 之外,所以它是不可点击的。有什么解决办法吗?

注意:我知道我可以将子视图添加到 presentedView,然后将 dismissButton 移到视图之外,但是如果我这样做,按钮将以与控制器其余部分相同的方式呈现,而不是像我一样淡入想要它(不向上滑动)。

@available(iOS 13.0, *)
open class CUICFiveSixthPopUpTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
    
    let dimmingColor: UIColor!
    
    public init(dimmingColor: UIColor) {
        self.dimmingColor = dimmingColor
        super.init()
    }
    
    public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        return CUICFiveSixthPopUpPresentationController(presentedViewController: presented, presenting: presenting, dimmingColor: dimmingColor)
    }
}

@available(iOS 13.0, *)
open class CUICFiveSixthPopUpPresentationController: UIPresentationController {
    open override var frameOfPresentedViewInContainerView: CGRect {
        let bounds = presentingViewController.view.bounds
        
        let size = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height*5/6)
        let origin = CGPoint(x: bounds.midX - size.width / 2, y: UIScreen.main.bounds.height - size.height)
        return CGRect(origin: origin, size: size)
    }
    
    public init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?, dimmingColor: UIColor) {
        super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
        
        presentedView?.autoresizingMask = [
            .flexibleTopMargin,
            .flexibleBottomMargin,
            .flexibleLeftMargin,
            .flexibleRightMargin
        ]
        
        presentedViewController.view.layer.cornerRadius = viewRadius
        presentedViewController.view.clipsToBounds = true
        dimmingView.backgroundColor = dimmingColor
        dismissButton.backgroundColor = dimmingColor.lighter()
        
        presentedView?.translatesAutoresizingMaskIntoConstraints = true
    }
    
    let iconSize: CGFloat = 40
    let viewRadius: CGFloat = 35
    
    let dimmingView: UIView = {
        let dimmingView = UIView(frame: .zero)
        dimmingView.translatesAutoresizingMaskIntoConstraints = false
        return dimmingView
    }()
    
    let dismissButton: UIButton = {
        let dismissButton = UIButton(frame: .zero)
        dismissButton.tintColor = .white
        dismissButton.alpha = 0.8
        dismissButton.setImage(.close, for: .normal)
        dismissButton.translatesAutoresizingMaskIntoConstraints = false
        return dismissButton
    }()
    
    @objc private func dimmingViewTapped(_ sender: UITapGestureRecognizer) {
        let point = sender.location(in: presentingViewController.view!)
        if dismissButton.frame.contains(point) {
            presentedViewController.dismiss(animated: true)
        }
    }
    
    open override func presentationTransitionWillBegin() {
        super.presentationTransitionWillBegin()
        
        let superview = presentingViewController.view!
        let presentedView = presentedView!
        
        superview.addSubview(dimmingView)
        superview.addSubview(dismissButton)
        
        NSLayoutConstraint.activate([
            dimmingView.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
            dimmingView.trailingAnchor.constraint(equalTo: superview.trailingAnchor),
            dimmingView.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
            dimmingView.topAnchor.constraint(equalTo: superview.topAnchor),
            
            dismissButton.topAnchor.constraint(equalTo: superview.topAnchor, constant: .marginFromTopOfScreen),
            dismissButton.leftAnchor.constraint(equalTo: superview.leftAnchor, constant: .marginLeft),
            dismissButton.heightAnchor.constraint(equalToConstant: iconSize),
            dismissButton.widthAnchor.constraint(equalToConstant: iconSize),
        ])
        dismissButton.layer.cornerRadius = iconSize/2
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dimmingViewTapped(_:)))
        dimmingView.addGestureRecognizer(tapGesture)
        
        dimmingView.alpha = 0
        presentingViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] _ in
            self?.dimmingView.alpha = 1
        }, completion: nil)
    }
    
    open override func dismissalTransitionWillBegin() {
        super.dismissalTransitionWillBegin()
        
        presentingViewController.transitionCoordinator?.animate(alongsideTransition: { _ in
            self.dimmingView.alpha = 0
        }, completion: { _ in
            self.dimmingView.removeFromSuperview()
        })
    }
}
ios swift xcode uibutton uipresentationcontroller
© www.soinside.com 2019 - 2024. All rights reserved.