问题描述
这个按钮还有一个三角形的可点击区域。为了做到这一点,我创建了一个 UIButton 类,如下所示。
按钮的可点击区域为三角形,但按钮的边框仍为矩形。如何使按钮的框架成为三角形?如果有这样的方式,我不会使用 bezierpath 绘制可点击区域,因为框架已经是一个三角形。
谢谢。
class triangleShapeButton: UIButton {
private let triangle = UIBezierPath()
override func draw(_ rect: CGRect) {
super.draw(rect)
triangle.move(to: CGPoint(x: rect.width,y: rect.height))
triangle.addLine(to: CGPoint(x:rect.width/2,y: 0))
triangle.addLine(to: CGPoint(x: 0,y:rect.height))
triangle.close()
}
override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) {
// This is for allow touches only in shape area.
if triangle.contains(touches.first?.location(in: self) ?? .zero) {
super.touchesBegan(touches,with: event)
}
}
编辑:我要创建的是一个圆形按钮设置如下。在这样做的同时,一些三角形按钮的矩形框与下一个三角形按钮重叠。这会导致阻止某些三角形按钮的可点击区域。我尝试更改图层层次结构,但至少有 1 个按钮仍与另一个按钮重叠。如果我不能改变框架,我该如何解决这个问题?
非常感谢
解决方法
我在您现有的代码中添加了一些代码,您可以尝试一下。它可能会帮助你。 我建议你要求矩形图像。
class TriangleShapeButton: UIButton {
let triangle = UIBezierPath()
let triangleLayer = CAShapeLayer()
override func draw(_ rect: CGRect) {
super.draw(rect)
triangle.move(to: CGPoint(x: rect.width,y: rect.height))
triangle.addLine(to: CGPoint(x:rect.width/2,y: 0))
triangle.addLine(to: CGPoint(x: 0,y:rect.height))
triangleLayer.path = triangle.cgPath
triangleLayer.fillColor = UIColor.red.cgColor
self.layer.addSublayer(triangleLayer)
triangle.close()
}
override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) {
// This is for allow touches only in shape area.
if triangle.contains(touches.first?.location(in: self) ?? .zero) {
super.touchesBegan(touches,with: event)
}
}
}
,
您原来改变 UIView 形状的方法是不可能的。每个 UIView 在底层都是一个矩形,因此在您的情况下相邻的三角形必然会重叠。
但是有一种不同的方法:
您可以为整个圆形视图创建单个类。在该类中,您修改 drawRect
函数,使单个三角形(或圆段)彼此相邻绘制。
在这个类中,您可以重写 touchesBegan
方法。在那里您可以使用 touches.first?.location(in: self)
检查触摸位置。这会给你一个CGPoint
。然后您可以手动检查触摸发生在哪个三角形并相应地执行操作。
以下是我的建议:
使用 CAShapeLayers 绘制形状。如果您最终想用图像填充这些形状,请查看设置图层内容为 CGImage 的图层。添加另一个 CAShapeLayer 以绘制形状的边框。然后应用 CAShapeLayer 作为蒙版,将图像裁剪为三角形/圆形楔形。
现在,为了弄清楚用户点击了什么: 构建一组形状路径及其框架矩形。当您在视图中点击时,首先遍历矩形数组并找到所有包含点击点的矩形。 (可能不止一个。)
然后循环遍历矩形中包含抽头的较小数组,并使用 UIBezierPath.contains(point:)
或 CGPath.contains(_:using:transform:)
找出您的哪个形状实际包含抽头点。
首先将数组过滤为仅那些帧包含抽头点的形状,您可以使用非常快速的测试来减少必须使用慢得多的路径 contains() 方法检查的形状数量。