Oleg G.
Oleg G.

Reputation: 588

SwiftUI Nested GeometryReader - Breaking UI

So I am trying to understand why my subview (TopView) is having weird resizing issues.

Here is the sample

import SwiftUI

struct ContentView: View {
    @State var isInterfaceHidden: Bool = false

    var body: some View {
        VStack(spacing: 0, content: {
            if !isInterfaceHidden {
                TopView()
                    .background(Color.yellow)
            }
            Rectangle()
                .foregroundColor(Color.red)
                /// We make sure it won't cover the top and bottom view.
                .zIndex(-1)
            if !isInterfaceHidden {
                Rectangle()
                    .foregroundColor(Color.yellow)
                    .frame(height: 80)
            }
        })
        .navigationBarTitle("")
        .navigationBarHidden(true)
    }
}

struct TopView: View {var body: some View {
        HStack(content: {
            VStack(spacing: 0, content: {
                Text("Text to show, it is a title.")
                    .tracking(0.2)
                    .foregroundColor(.white)
                    .lineLimit(1)
                GeometryReader(content: { geometry in
                    Text("Text to show, it is a subline.")
                        .tracking(0.2)
                        .foregroundColor(.white)
                        .lineLimit(1)
                })
                .background(Color.purple)
            })
        })
        .padding([.leading, .trailing], 20)
    }
}

enter image description here

I tried to set a .fixedSize() like this:

GeometryReader(content: { geometry in
    Text("Text to show, it is a subline.")
        .tracking(0.2)
        .foregroundColor(.white)
        .lineLimit(1)
    })
    .background(Color.purple)

enter image description here

But it is not fitting the text exactly, so I am not sure if this is the right solution. Do you guys have any idea?

Upvotes: 2

Views: 4912

Answers (3)

Renê X
Renê X

Reputation: 69

GeometryReader fit to View

If you're looking for the GeometryReader to not affect the size of your view, you should make an inversion. The view that you return inside the GeometryReader should be out, and the GeometryReader itself should be put in a background or in a overlay of that View.

Text("Text to show, it is a subline.")
    .tracking(0.2)
    .foregroundColor(.white)
    .lineLimit(1)
    .overlay(
        GeometryReader(content: { geometry -> Color in
            print(geometry.frame(in: .global))
            return Color.clear
        })
    )
    .background(Color.purple)

Either way (background or overlay), would solve your problem. Try changing overlay to background to see.

Just remember to return a Color.clear, this way, the GeometryReader becomes invisible and it doesn't change the View.

Upvotes: 3

Andrew Lipscomb
Andrew Lipscomb

Reputation: 1046

Be aware that GeometryReader has had what appears to be a regression as of 14.0 (26/Sep/20) - or perhaps a wonderfully undocumented change of behaviour - with weighting layouts towards the topleft corner - rather than the center.

This has only appeared with apps I developed and built with XCode 12 - an XCode-11-compiled-app running on iOS 14 did not exhibit the issue. Most tutorials on the net will be assuming this worked the way it did in iOS 13/XCode 11 and your code may function differently

iOS 14 has Changed (or broken?) SwiftUI GeometryReader for a more involved question with the same issues

Upvotes: 2

Kyokook Hwang
Kyokook Hwang

Reputation: 2762

As far as I know, GeometryReader passes back its parent a size that is given by the parent unless you set frame() to GeometryReader explicitly. Even so, If you want to fit the area of GeometryReader to the Text view (exactly your custom view), you will have to calculate a height of the custom view by using preference or anchorPreference and then set it as a height of GeometryReader in order to let the parent know what size it needs to assign.

I hope the following link will be helpful.
https://swiftui-lab.com/communicating-with-the-view-tree-part-1/

Upvotes: 2

Related Questions