我需要有一个带边框的视图,并且只能点击边框。
这是我创建自定义视图的代码,但是当我添加手势时,所有视图都变为可点击。
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()
}
}
所以我会点击我顶视图下的视图,这个视图会在前面并且可以点击,所以我不能添加更小的子视图
答案 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
的结果:
如果您需要多个视图,有两种可能的选择:
CAShapeLayer
存储在一个CustomView
内,并在point
功能CustomView
,并在UITapGestureRecognizer
点击操作