0

Xcode 11 Beta 4 deprecated .relativeSize as well as .relativeWidth and .relativeHeight (see this related post).

So what is the alternative?

I want to create an overlay that has a width relative to it's parent.

Let's say I have the following main view

struct MainView: View {
  var body: some View {
    ZStack(alignment: .topLeading) {
        BackgroundView()
        SideBarView()
          .frame(idealWidth: 200)
          .fixedSize(horizontal: true, vertical: false)
    }
  }
}

With a simple BackgroundView and SideBarView as well those work as expected.

struct SideBarView: View {
    var body: some View {
        Rectangle()
            .foregroundColor(.green)
    }
}

struct BackgroundView: View {
    var body: some View {
        Rectangle()
            .foregroundColor(.red)
    }
}

This was suggested in the release notes and this answer.

How can I avoid to hardcode those values as I could before by using .relativeWidth(0.3) instead of .frame(idealWidth:)?1


1Note: Using .relativeWidth never actually worked, e.g. using 0.3 as a relative value never resulted in a view that was 30 % of the width of the parent, but you could get close to your desired result through trial-and-error.

jlsiewert
  • 3,494
  • 18
  • 41

1 Answers1

1

There are multiple ways to achieve it, one way is using .overlay instead of ZStack. The view you use in the overlay, will get the size of the BackgroundView offered by the parent. Then you simply use GeometryReader to get the width and multiply it by 0.7:

struct ContentView: View {
  var body: some View {
    BackgroundView().overlay(SideBarView())
  }
}

struct SideBarView: View {
    var body: some View {
        GeometryReader { proxy in
            HStack {
                Spacer()

                Rectangle()
                    .frame(width: proxy.size.width * 0.7)
                    .fixedSize(horizontal: true, vertical: false)
                    .foregroundColor(.green)
            }
        }
    }
}

struct BackgroundView: View {
    var body: some View {
        Rectangle()
            .foregroundColor(.red)
    }
}
kontiki
  • 37,663
  • 13
  • 111
  • 125
  • That worked, thank you. Although I find it weird that it is so complicated for a relative common and simple feature. – jlsiewert Jul 24 '19 at 06:33