【问题标题】:How to create one sided arrowed label如何创建单面箭头标签
【发布时间】:2019-05-02 03:21:06
【问题描述】:

我不是在寻找代码 sn-p。我只是想知道如何开发如下所示的 UI 组件。我对创建它有多种想法,但很想知道最好的方法

  • 创建标签并对其图层进行一些操作
  • 设置背景图片并在标签上添加文字
  • 设置上面有文字的图片

开发它的好方法是什么。请有任何建议。

【问题讨论】:

  • 用 UIBezierPath 画出来。
  • 感谢@Ryan 的建议。我期待更多建议,然后将最终确定方法。

标签: ios swift uilabel


【解决方案1】:

您想显示单行文本。您可以为此使用UILabel

你有一个想要填充的形状。您可以为此使用CAShapeLayer。最好将形状层包裹在UIView 子类中,以便 UIKit 可以正确布局。

您想将文本放在形状上,因此使用父视图将标签和形状组合为子视图。

import UIKit

class TagView: UIView {

    init() {
        super.init(frame: .zero)
        addSubview(background)
        addSubview(label)

        background.translatesAutoresizingMaskIntoConstraints = false
        label.translatesAutoresizingMaskIntoConstraints = false

        label.setContentHuggingPriority(.defaultHigh + 10, for: .horizontal)
        label.setContentHuggingPriority(.defaultHigh + 10, for: .vertical)

        NSLayoutConstraint.activate([
            background.heightAnchor.constraint(equalTo: label.heightAnchor, constant: 4),
            background.centerYAnchor.constraint(equalTo: label.centerYAnchor),
            background.widthAnchor.constraint(equalTo: label.widthAnchor, constant: 20),
            background.centerXAnchor.constraint(equalTo: label.centerXAnchor, constant: -2),
            leadingAnchor.constraint(equalTo: background.leadingAnchor),
            trailingAnchor.constraint(equalTo: background.trailingAnchor),
            topAnchor.constraint(equalTo: background.topAnchor),
            bottomAnchor.constraint(equalTo: background.bottomAnchor),
            ])
    }

    let label = UILabel()

    private let background = BackgroundView()

    private class BackgroundView: UIView {
        override class var layerClass: AnyClass { return CAShapeLayer.self }

        override func layoutSubviews() {
            super.layoutSubviews()
            layoutShape()
        }

        private func layoutShape() {
            let layer = self.layer as! CAShapeLayer
            layer.fillColor = #colorLiteral(red: 0.731529057, green: 0.8821037412, blue: 0.9403864741, alpha: 1)
            layer.strokeColor = nil

            let bounds = self.bounds
            let h2 = bounds.height / 2
            let path = UIBezierPath()
            path.move(to: CGPoint(x: 0, y: h2))
            path.addLine(to: CGPoint(x: h2, y: 0))
            path.addLine(to: CGPoint(x: bounds.maxX - h2, y: 0))
            path.addArc(withCenter: CGPoint(x: bounds.maxX - h2, y: h2), radius: h2, startAngle: -.pi/2, endAngle: .pi/2, clockwise: true)
            path.addLine(to: CGPoint(x: h2, y: bounds.maxY))
            path.close()

            layer.path = path.cgPath
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

import PlaygroundSupport
let root = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
root.backgroundColor = .white
PlaygroundPage.current.liveView = root

let tag = TagView()
tag.translatesAutoresizingMaskIntoConstraints = false
tag.label.text = "CURRENT"
root.addSubview(tag)
NSLayoutConstraint.activate([
    tag.centerXAnchor.constraint(equalTo: root.centerXAnchor),
    tag.centerYAnchor.constraint(equalTo: root.centerYAnchor),
])

结果:

【讨论】:

  • 我喜欢你实现这一目标的方式。我欠你的示例代码。你给了我探索UIBezierPath 的动力。谢谢你的指导。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多