如何绘制背景颜色可变的自定义图标?

时间:2019-01-06 11:30:19

标签: ios

我正在尝试重建与图片所示完全相同的东西。

enter image description here

根据手指的位置,图钉的背景颜色应相应更改为图像颜色。但这不是重点。我只是在寻找一种方法来创建具有可变背景颜色的图钉。

我尝试使用内部和外部具有透明性的png作为UIView的遮罩,但是那样我只会得到没有任何填充的边框。

enter image description here

2 个答案:

答案 0 :(得分:0)

使用具有渲染功能的UIImage作为模板图像是实现此目的的一种非常简单的方法。

这是一个演示项目,您可以在其中放置大头针图像(确保其为30x30点)以确保其正常工作。

https://github.com/joelesli/TemplateImageDemo/tree/master

enter image description here

要更改边框和背景,您可以

  1. 使用单独的图像作为边框
  2. 尝试并使用 imageView.layer.border和.borderColor属性(尚未尝试 它)

答案 1 :(得分:0)

可能不是一个完美的解决方案,但是您可以像这样创建自定义PinView类:

@IBDesignable
class PinView: UIView {

    @IBInspectable var fillColor: UIColor = .black {
        didSet {
            setNeedsDisplay()
        }
    }

    @IBInspectable var borderColor: UIColor = .black {
        didSet {
            setNeedsDisplay()
        }
    }

    @IBInspectable var borderWidth: CGFloat = 0.0 {
        didSet {
            setNeedsDisplay()
        }
    }

    override func draw(_ rect: CGRect) {
        let px = rect.midX
        let py = rect.maxY - borderWidth

        let cx = rect.width / 2
        let cy = rect.width / 2

        let radius = rect.width / 2 - (borderWidth / 2)

        let dx = cx - px;
        let dy = cy - py;

        let dd = sqrt(dx * dx + dy * dy);
        let a = asin(radius / dd)
        let b = atan2(dy, dx)

        var t = b - a
        let ta = CGPoint(x: radius * sin(t),
                         y: radius * -cos(t))

        t = b + a
        let tb = CGPoint(x: radius * -sin(t),
                         y: radius * cos(t))

        // create path
        let path = UIBezierPath()

        path.move(to: CGPoint(x: px, y: py))
        path.addLine(to: CGPoint(x: cx + ta.x, y: cy + ta.y))

        let startAngle = atan2((cy + ta.y) - cy, (cx + ta.x) - cx)
        let endAngle = atan2((cy + tb.y) - cy, (cx + tb.x) - cx)

        path.addArc(withCenter: CGPoint(x: cx, y: cy),
                    radius: radius,
                    startAngle: startAngle,
                    endAngle: endAngle,
                    clockwise: true)

        path.close()

        // prepare drawing colors / settings
        fillColor.setFill()
        borderColor.setStroke()

        path.lineWidth = borderWidth

        // draw
        path.fill()
        path.stroke()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        sharedInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        sharedInit()
    }

    private func sharedInit() {
        backgroundColor = .clear
        isOpaque = false
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        sharedInit()
    }

}

然后,您可以根据需要简单地更新fillColorborderColorborderWidth