3

Trying to build a bar graph element in SwiftUI whose width is proportional to its parent view based on the value of the element. Here's a boiled down version of the problem:

struct BarView : View {
var body: some View {
    Color.purple
        .relativeWidth(0.5)
    }
}

...which yields:

enter image description here

I expected the relativeWidth modifier to use its parent which should be the width of the screen, so the color view should be half the width of the screen and centered. If the view is embedded in a frame view, it works as expected:

struct BarView : View {
    var body: some View {
        Color.purple
            .relativeWidth(0.5)
            .frame(width: 200, height: 200)
    }
}

In frame

I need the view to be flexible inside its container without specifying a frame. I realize there's the GeometryReader, but this seems like a bit of a hack when relativeWidth seems to be exactly what's needed here. Any ideas?

1
  • It's a beta product and who knows, maybe it is behaving exactly how it's intended to behave. Commented Jul 4, 2019 at 3:58

1 Answer 1

1

Well, .relativeWidth() is gone with beta4... so I am updating my answer.

As an alternative to GeometryReader, that comes with its own inconveniences, in your case using a Shape may be a good alternative.

The path() function where you define your shape, has a rect parameter that helps you with your drawing. Here's a solution:

import SwiftUI

struct BarShape: Shape {
    let percent: CGFloat

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

        let fillPart = CGRect(x: 0, y: 0, width: rect.size.width * percent, height: rect.size.height)

        var p = Path()

        p.addRoundedRect(in: fillPart, cornerSize: CGSize(width: 8, height: 8))

        return p
    }
}

struct ContentView: View {
    var body: some View {
        BarShape(percent: 0.7).fill(Color.purple)
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Figured as much, but it seemed just as likely I didn’t understand the system. Still coming to grips with the new concepts. Appreciate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.