空视图,只有可点击的边框

时间:2017-11-13 09:46:13

标签: ios swift3

我需要有一个带边框的视图,并且只能点击边框。

这是我创建自定义视图的代码,但是当我添加手势时,所有视图都变为可点击。

class RectangleView: UIView {

  override func draw(_ rect: CGRect) {
    let aPath = UIBezierPath()
    aPath.move(to: CGPoint(x:0, y: 0))
    aPath.addLine(to: CGPoint(x:rect.width, y: 0))
    aPath.addLine(to: CGPoint(x:rect.width, y:rect.height))
    aPath.addLine(to: CGPoint(x:0, y:rect.height))
    aPath.close()
    UIColor.green.setStroke()
    aPath.stroke()
    UIColor.clear.setFill()
    aPath.fill()
  }
}

编辑,这是其他应用的截图 enter image description here

所以我会点击我顶视图下的视图,这个视图会在前面并且可以点击,所以我不能添加更小的子视图

1 个答案:

答案 0 :(得分:1)

这里最正确的方法是覆盖func point(inside point: CGPoint, with event: UIEvent?) -> Bool子类的UIView

以下是示例:

class CustomView: UIView {
    private let shapeLayer = CAShapeLayer()

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

        setupShapeLayer()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupShapeLayer() {
        //Draw your own shape here

        shapeLayer.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)

        let innerPath = UIBezierPath(arcCenter: center, radius: frame.width / 3, startAngle: CGFloat(0), endAngle: CGFloat.pi * 2, clockwise: true)

        let outerPath = UIBezierPath(arcCenter: center, radius: frame.width / 4, startAngle: CGFloat(0), endAngle: CGFloat.pi * 2, clockwise: true)

        //Subtract inner path
        innerPath.append(outerPath.reversing())

        shapeLayer.path = innerPath.cgPath
        shapeLayer.lineWidth = 10
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.fillColor = UIColor.yellow.cgColor

        layer.addSublayer(shapeLayer)
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return shapeLayer.path?.contains(point) ?? false
    }
}

现在您可以添加UITapGestureRecognizer来检查其工作原理:

class ViewController: UIViewController {

    @IBOutlet weak var resultLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let customView = CustomView.init(frame: view.frame)
        view.addSubview(customView)

        let recognizer = UITapGestureRecognizer(target: self, action: #selector(tapAction))
        view.addGestureRecognizer(recognizer)
    }

    @objc func tapAction(_ sender: UITapGestureRecognizer) {
        let location = sender.location(in: sender.view)
        let subview = view?.hitTest(location, with: nil)

        if subview is CustomView {
            resultLabel.text = "CustomView"
        }
        else {
            resultLabel.text = "Other"
        }
    }
}

tapAction的结果:

enter image description here

如果您需要多个视图,有两种可能的选择:

  • CAShapeLayer存储在一个CustomView内,并在point功能
  • 中重复执行
  • 为每个实例添加CustomView,并在UITapGestureRecognizer点击操作
  • 内进行迭代