在 Swift 中制作按钮三角形而不是矩形的框架

问题描述

我有一个按钮,里面有一个三角形的图像。如下所示。

enter image description here

这个按钮还有一个三角形的可点击区域。为了做到这一点,我创建了一个 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 个按钮仍与另一个按钮重叠。如果我不能改变框架,我该如何解决这个问题?

非常感谢

enter image description here

解决方法

我在您现有的代码中添加了一些代码,您可以尝试一下。它可能会帮助你。 我建议你要求矩形图像。

   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)
                
            }
        }
    }

enter image description here

,

您原来改变 UIView 形状的方法是不可能的。每个 UIView 在底层都是一个矩形,因此在您的情况下相邻的三角形必然会重叠。

但是有一种不同的方法:

您可以为整个圆形视图创建单个类。在该类中,您修改 drawRect 函数,使单个三角形(或圆段)彼此相邻绘制。

在这个类中,您可以重写 touchesBegan 方法。在那里您可以使用 touches.first?.location(in: self) 检查触摸位置。这会给你一个CGPoint。然后您可以手动检查触摸发生在哪个三角形并相应地执行操作。

,

以下是我的建议:

使用 CAShapeLayers 绘制形状。如果您最终想用图像填充这些形状,请查看设置图层内容为 CGImage 的图层。添加另一个 CAShapeLayer 以绘制形状的边框。然后应用 CAShapeLayer 作为蒙版,将图像裁剪为三角形/圆形楔形。

现在,为了弄清楚用户点击了什么: 构建一组形状路径及其框架矩形。当您在视图中点击时,首先遍历矩形数组并找到所有包含点击点的矩形。 (可能不止一个。)

然后循环遍历矩形中包含抽头的较小数组,并使用 UIBezierPath.contains(point:)CGPath.contains(_:using:transform:) 找出您的哪个形状实际包含抽头点。

首先将数组过滤为仅那些帧包含抽头点的形状,您可以使用非常快速的测试来减少必须使用慢得多的路径 contains() 方法检查的形状数量。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...