【问题标题】:Add text to the shape in center将文本添加到中心的形状
【发布时间】:2020-09-17 10:32:54
【问题描述】:

我创建了一个看起来像这样的视图:

我想为视图中的每个段添加一个文本标签,使其居中对齐。每个段都是一个自定义按钮,在指定的层中也会响应。当我尝试做 button.setTitle 时,由于按钮的框架不同,它不会与形状层对齐。任何人都可以建议如何实现同样的目标。

我尝试创建另一个函数并在创建形状和按钮时调用它。

func addText(_ stringValue: String, to shapeLayer: CAShapeLayer) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            let textlayer = CATextLayer()
            if let rect = shapeLayer.path?.boundingBox {
//                print(rect)
                textlayer.frame = CGRect(x: rect.origin.x + rect.size.width/2, y:rect.origin.y + rect.size.height/2, width: 20, height: 20)
                textlayer.fontSize = 12
                textlayer.alignmentMode = .center
                textlayer.string = stringValue
                textlayer.backgroundColor = UIColor.clear.cgColor
                textlayer.foregroundColor = UIColor.black.cgColor
                shapeLayer.addSublayer(textlayer)
            }
        }
    }

但这不起作用,因为文本与图层重叠。任何人都可以提出一种实现相同目标的方法吗?

编辑:

每个片段都有文字,我只是添加了一些文字来给出一个想法。

编辑 2:

创建视图的代码:

        for segment in outerSegments { 
            let endAngle = startAngle + 2 * .pi * (segment.value / valueCount)
            let shape = CAShapeLayer()
            let path: UIBezierPath = UIBezierPath(arcCenter: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
            path.addLine(to: viewCenter)
            path.close()
            shape.path = path.cgPath
            shape.fillColor = segment.color.cgColor
            shape.strokeColor = UIColor.black.cgColor
            shape.borderWidth = 1.0
            shape.borderColor = UIColor.black.cgColor
            shape.name = "\(i)"
            datamap[shape.name ?? ""] = data[i]
            let label = CATextLayer()

            //addText(data[i], to: shape)
            let b = MyButton(type: .custom)
            b.path = path
            b.backgroundColor = UIColor.clear
            b.tag = Int(data[i].asciiValues[0])
            b.backgroundColor = UIColor.clear
            self.layer.addSublayer(shape)
            let frameRect = shape.bounds
            b.frame = frameRect
            let sine = sin(startAngle)
            let cosine = cos(startAngle)
            print("\(sine)  \(data[i])")
            b.addTarget(self, action: #selector(ButtonClicked(_:)), for: .touchUpInside)
            self.addSubview(b)
            self.bringSubviewToFront(b)
            self.isUserInteractionEnabled = true
            //layer.addSublayer(shape)
            startAngle = endAngle
            i += 1
        }
        valueCount = innerSegments.reduce(0, {$0 + $1.value})
        startAngle = 0
        i = 100
        for segment in innerSegments {
            let endAngle = startAngle + 2 * .pi * (segment.value / valueCount)
            let shape = CAShapeLayer()
            let path: UIBezierPath = UIBezierPath(arcCenter: viewCenter, radius: 2*radius/3, startAngle: startAngle, endAngle: endAngle, clockwise: true)
            path.addLine(to: viewCenter)
            path.close()
            shape.path = path.cgPath
            shape.strokeColor = UIColor.black.cgColor
            shape.fillColor = segment.color.cgColor
            shape.borderWidth = 1.0
            shape.borderColor = UIColor.black.cgColor
            shape.name = "\(i)"
            datamap[shape.name ?? ""] = data[i-100]
            addText(data[i-100], to: shape)
            let b = MyButton(type: .custom)
            b.path = path
            b.backgroundColor = UIColor.clear
            self.layer.addSublayer(shape)
            let frameRect = shape.bounds
            b.frame = frameRect
            b.tag = Int(data[i-100].asciiValues[0])

            b.addTarget(self, action: #selector(ButtonClicked(_:)), for: .touchUpInside)
            self.addSubview(b)
            self.bringSubviewToFront(b)

            self.isUserInteractionEnabled = true
            //layer.addSublayer(shape)
            startAngle = endAngle
            i += 1
        }
        valueCount = innerMostSegments.reduce(0, {$0 + $1.value})
        startAngle = 0
        i = 1000
        for segment in innerMostSegments {
            let endAngle = startAngle + 2 * .pi * (segment.value / valueCount)
            let shape = CAShapeLayer()
            let path: UIBezierPath = UIBezierPath(arcCenter: viewCenter, radius: radius/3, startAngle: startAngle, endAngle: endAngle, clockwise: true)
            path.addLine(to: viewCenter)
            path.close()
            shape.path = path.cgPath
            shape.fillColor = segment.color.cgColor
            shape.strokeColor = UIColor.black.cgColor
            shape.borderWidth = 1.0
            shape.borderColor = UIColor.black.cgColor
            shape.name = "\(i)"
            datamap[shape.name ?? ""] = data[i-1000]
            addText(data[i-1000], to: shape)
            let b = MyButton(type: .custom)
            b.path = path
            b.backgroundColor = UIColor.clear
            self.layer.addSublayer(shape)
            let frameRect = shape.bounds
            b.frame = frameRect
            b.tag = Int(data[i-1000].asciiValues[0])
            b.addTarget(self, action: #selector(ButtonClicked(_:)), for: .touchUpInsid)
            self.addSubview(b)
            self.bringSubviewToFront(b)
            self.isUserInteractionEnabled = true
            startAngle = endAngle
            i += 1
        }
    }

【问题讨论】:

  • 为什么不使用不同的视图并旋转每个视图?
  • @MojtabaHosseini 我没把你带到那里,你能解释一下吗。
  • 你能画一下吗?在标准Preview 应用程序中(查看->显示标记工具栏)文本应该是什么样子?
  • @OlhaPavliuk 我已经添加了我想要的输出,这可能会有所帮助

标签: ios swift


【解决方案1】:

大概,您正在使用数学来计算“辐条”和“弧线”?

对于每个线段,您可能需要平分构成边的角度(黄线),然后沿着该线在弧之间计算一个点(红点):

该点成为标签框架的中心。

【讨论】:

  • 我使用let path: UIBezierPath = UIBezierPath(arcCenter: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) 创建了路径,因此我可以获得起点和终点角度的正弦和余弦。我不确定如何计算。能否详细说明。
  • @dper - 每个“部分”都是UIView吗?还是整个图纸都是一个视图?如果您显示用于生成视图的代码,我会更容易帮助计算。
  • 我已编辑问题以添加代码以创建细分。希望对您有所帮助,这反过来又对我有所帮助:P
  • 我也尝试将 setTitle 添加到按钮中,但标题位于按钮框架的中间,它是矩形而不是分段。我还想过尝试使用 button.contentEdgeInsets 的方法并尝试使用它应用布局但没有成功
  • @dper - 我的一天结束了。早上我可以再看看这个。
猜你喜欢
  • 1970-01-01
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多