Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SwiftUI's relativeWidth only works inside frame view

Tags:

swiftui

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?

like image 707
smr Avatar asked Feb 19 '26 10:02

smr


1 Answers

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)
    }
}
like image 180
kontiki Avatar answered Feb 27 '26 09:02

kontiki