ios - 空 View ,只有可点击的边框

标签 ios swift3

我需要一个带边框的 View ,并且只有边框应该是可点击的。

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

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

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

最佳答案

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

例子:

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

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

  • CAShapeLayer 存储在一个 CustomView 中,并在 point 函数中对其进行迭代
  • 为每个实例添加 CustomView 并在 UITapGestureRecognizer tap action 中迭代它

关于ios - 空 View ,只有可点击的边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47261289/

相关文章:

ios - 如何构建具有特定行数的 TableView ?

ios - 如何在 uitableview 自定义单元格中隐藏标签

ios - 如何在 iOS 中退出键盘

swift3 - 如何在 Swift 3.0 的右侧创建侧边菜单?

ios - 在 iOS 中使用 SecRandomCopyBytes( ) 的随机 256 位 key

iOS Swift 3 以编程方式将文件复制到 iCloud Drive

swift3 - 检查互联网连接 (iOS 10)

ios - AVAudioSession 总是返回相同的 outputVolume

ios - 更新UI时如何同时执行2个函数

ios - 注册单元重用调用实际上有什么作用?