在叠加视图上启用用户交互

时间:2019-03-14 09:34:27

标签: swift

我正在UITableView的顶部创建一个变暗的叠加层,我想突出显示其中一行。我可以突出显示它,但是如何启用用户交互(例如,点击单元格)?

func addFullScreenDarkOverlay(){
    let viewDarkOverlay = UIView()
    viewDarkOverlay.alpha = 0.5
    viewDarkOverlay.backgroundColor = .black
    viewDarkOverlay.frame = UIApplication.shared.keyWindow!.frame

    //  add dummy hole (will change it to the frame of the particular cell)
    let holeFrame = CGRect(x: 0, y: 0, width: viewDarkOverlay.frame.width/2, height: viewDarkOverlay.frame.height/2)

    // Do any additional setup after loading the view.
    let path = CGMutablePath()
    // Dark background
    path.addRect(CGRect(x: 0, y: 0, width: viewDarkOverlay.frame.width, height: viewDarkOverlay.frame.height))
    // White/spotlight path
    path.addRect(holeFrame)

    let maskLayer = CAShapeLayer()
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.path = path;
    maskLayer.fillRule = kCAFillRuleEvenOdd

    viewDarkOverlay.layer.mask = maskLayer
    viewDarkOverlay.clipsToBounds = true


    UIApplication.shared.keyWindow!.addSubview(viewDarkOverlay)


}

2 个答案:

答案 0 :(得分:0)

删除叠加层视图中的用户交互,您将能够在其下面的视图中选择行:

viewDarkOverlay.isUserInteractionEnabled = false

如果您只想在整个内部进行选择,则可以使用如下委托将触摸从叠加视图转移到父视图:

protocol OverlaySelection: class{
    func selected(with touch: UITouch?)
}

class OverlayView: UIView{
    weak var delegate : OverlaySelection?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        delegate?.selected(with: touches.first)
    }
}

然后在您的父视图中:

func addFullScreenDarkOverlay(){
     let viewDarkOverlay = OverlayView()
     viewDarkOverlay.delegate = self
    //other config..
 }

 //Delegate
func selected(with touch: UITouch?) {
   if let location = touch?.location(in: self.view){
 //Here you check if this point is inside the whole and if it is you select 
 //the row, if not just return
  let indexpath = tableview.indexPathForRow(at: location)
  tableview.selectRow(at: indexpath, animated: true, scrollPosition: .bottom)
   }
}

答案 1 :(得分:0)

基本上,您可以禁用蒙版视图的用户交互,这会将所有触摸事件传递给下面的视图...但是,如果您只希望突出显示的区域(例如单元格)难以处理,则可以可以创建自定义UIView子类,重写hitTest方法,如下所示:

import UIKit

class MaskView: UIView {

    var hitableArea: CGRect {
        return CGRect(x: 0, y: 0, width: bounds.width * 0.5, height: bounds.height * 0.5)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        installMaskLayer()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        installMaskLayer()
    }

    private func installMaskLayer() {

        backgroundColor = UIColor.black.withAlphaComponent(0.5)

        let path = CGMutablePath()
        // Dark background
        path.addRect(bounds)
        // White/spotlight path
        path.addRect(hitableArea)

        let maskLayer = CAShapeLayer()
        maskLayer.backgroundColor = UIColor.black.cgColor
        maskLayer.path = path;
        maskLayer.fillRule = CAShapeLayerFillRule.evenOdd

        layer.mask = maskLayer
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01) {
            return nil;
        }

        if (hitableArea.contains(point)) {
            return nil
        }

        return self
    }
}

只需创建此自定义视图并将其添加到您的窗口中,现在您现在只能触摸单元格。