Edward Hasted
Edward Hasted

Reputation: 3423

SwiftUI: Absolute positioning of text on screen

Am updating a compass view from UIKit to SwiftUI. The original looks like this:

enter image description here

But haven't worked out how to display the text, currently nothing:

enter image description here

This is the code that I am using:

struct DisplayDirections: Shape {

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

        var path = Path()

        let outerRadius = 134.0

        var farX = 0.0

        var farY = 0.0

        let offset = 16.0

        var degree = 0.0

        var radians = 0.0

        for result in ["S", "SW", "W", "NW", "N", "NE", "E", "SE"] {

            radians = (CGFloat(degree) * .pi / 180.0)

            farX = outerRadius + cos(radians) * CGFloat(outerRadius) + offset

            farY = outerRadius + sin(radians) * CGFloat(outerRadius) + offset

            Text(result)

                .font(.title)

                .foregroundColor(.black)

                .background(.red)

                .position(x: farX, y: farY)

                .rotationEffect(.degrees(degree))

                .fixedSize()

            degree = degree + 45.0

            print(result) // Just to get some output so I know the loop is working

        }

        return path

    }

}

What am I doing wrong?

Upvotes: 0

Views: 538

Answers (1)

Edward Hasted
Edward Hasted

Reputation: 3423

Working, all thanks to Lorem Ipsum's hints. This code has to live in the main Stack and can't be called from Structs like the rest of the lines and circles that make up the clock face. The NSEW literals are put on with a similar construct to the degrees part which are listed below.

Swift UI Version

// Draw Degrees

ForEach(Array(stride(from: 0, to: 360, by: 10)), id: \.self) { index in
    let degree: Double = Double.pi * 2 / Double(360)
    let itemDegree = degree * Double(index)
    VStack {
        Text(String(index))
        .font(.system(size: 8))
        .foregroundColor(.black)
        Spacer()
    }
    .rotationEffect(.radians(itemDegree))
}
.frame(width: 288, height: 288)

Upvotes: 1

Related Questions