Vector with text drawing on image in SwiftUI

74 Views Asked by At

I want to draw Vectors that have a text in the middle on images, and be able to keep the text centered in the Vector

Example

Is there any easy way to do it with SwiftUI? Or any helpful libraries for something similar?

1

There are 1 best solutions below

0
Benzy Neez On BEST ANSWER

You can use a Shape to build the vector and then show it behind a Text label. Something like this:

struct Vector: Shape {
    let arrowWidth = CGFloat(15)
    let arrowHeight = CGFloat(12)
    let lineWidth = CGFloat(2)

    func path(in rect: CGRect) -> Path {
        var path = Path()

        // The line at the top
        path.move(to: CGPoint(x: rect.midX - (arrowWidth / 2), y: rect.minY + (lineWidth / 2)))
        path.addLine(to: CGPoint(x: rect.midX + (arrowWidth / 2) , y: rect.minY + (lineWidth / 2)))

        // The arrow at the top
        path.move(to: CGPoint(x: rect.midX, y: rect.minY + lineWidth))
        path.addLine(to: CGPoint(x: rect.midX + (arrowWidth / 2), y: rect.minY + arrowHeight))
        path.addLine(to: CGPoint(x: rect.midX - (arrowWidth / 2), y: rect.minY + arrowHeight))
        path.addLine(to: CGPoint(x: rect.midX, y: rect.minY + lineWidth))
        path.closeSubpath()

        // The central line
        path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY - lineWidth))

        // The arrow at the bottom
        path.move(to: CGPoint(x: rect.midX, y: rect.maxY - lineWidth))
        path.addLine(to: CGPoint(x: rect.midX + (arrowWidth / 2), y: rect.maxY - arrowHeight))
        path.addLine(to: CGPoint(x: rect.midX - (arrowWidth / 2), y: rect.maxY - arrowHeight))
        path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY - lineWidth))
        path.closeSubpath()

        // The line at the bottom
        path.move(to: CGPoint(x: rect.midX - (arrowWidth / 2), y: rect.maxY - (lineWidth / 2)))
        path.addLine(to: CGPoint(x: rect.midX + (arrowWidth / 2), y: rect.maxY - (lineWidth / 2)))
        return path
    }
}

struct ContentView: View {

    var body: some View {
        Color.yellow
            .frame(width: 300, height: 300)
            .overlay(alignment: .leading) {
                Text("400mm ± 5")
                    .padding(.vertical, 4)
                    .background(Color.yellow)
                    .frame(maxHeight: .infinity)
                    .background {
                        Vector()
                            .stroke(lineWidth: 2)
                            .overlay(
                                Vector().fill()
                            )
                    }
                    .padding(.leading, 10)
            }
    }
}

Vector