You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 自定义六边形遮罩UIButton标题无法显示问题求助

问题根因

你在draw(_ rect:)方法中新增的CAShapeLayer被添加到了图层栈的最顶层,直接覆盖了UIButton自带的titleLabel渲染图层,所以即使标题赋值正确也无法显示,和多边形遮罩的逻辑本身无关。

解决方案

1. 调整背景图层层级

将六边形背景图层插入到图层最底部,避免遮挡标题,同时优化图层创建逻辑,避免多次调用draw方法时重复生成冗余图层:

  • 首先在类中声明全局的shapeLayer属性,避免重复创建
  • 将addSublayer改为insertSublayer(at: 0),把背景层插到最下方
  • 仅在图层未添加时执行插入操作,避免重复叠加

2. 优化后的核心代码修改

class HexaButton: UIButton {
    var path: UIBezierPath!
    var category: Category!
    // 新增全局shapeLayer属性
    private let shapeLayer = CAShapeLayer()

    // 其他初始化、setupProperties方法保持不变

    override func layoutSubviews() {
        super.layoutSubviews()
        // 布局变化时触发重绘,适配按钮大小
        setNeedsDisplay()
    }

    override func draw(_ rect: CGRect) {
        let lineWidth: CGFloat = 5
        path = self.roundedPolygonPath(rect: self.bounds, lineWidth: lineWidth, sides: 6, cornerRadius: 10, rotationOffset: CGFloat(.pi / 2.0))

        shapeLayer.strokeColor = category.categoryColor.cgColor
        shapeLayer.fillColor = category.categoryColor.cgColor
        shapeLayer.path = path.cgPath
        // 仅第一次调用时插入到图层最底部
        if shapeLayer.superlayer == nil {
            layer.insertSublayer(shapeLayer, at: 0)
        }
    }

    // 其他touchDown、roundedPolygonPath方法保持不变
}

3. 额外优化建议

你当前在layoutSubviews中重复设置标题、字体、文字颜色的逻辑是冗余的,这些属性只需要在setupProperties中设置一次即可,不需要每次布局都重新赋值。

内容的提问来源于stack exchange,提问作者Alessign

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 00:21:01