1

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?

pawello2222
  • 23,992
  • 12
  • 59
  • 94
Oleg G.
  • 397
  • 2
  • 12
  • Why do you need that geometry reader around the text view? I don't see that the provided geometry is being used. – Denis Sep 23 '20 at 03:39
  • I am using a custom text that slides from right to left and left to right when the text is larger than the width available. I can share the sliding text component too if needed. but I didn't think it was necessary here, because it breaks the UI with or without it. – Oleg G. Sep 23 '20 at 03:44
  • Am I right that your custom text view works in a way that its height depends on its width? Like if you have longer text – it breaks into multiple lines in a similar way that the standard TextView does. – Denis Sep 23 '20 at 05:09
  • Yeah, but here, even without using the custom text it is still breaking my UI to make the view with the `GeometryReader` excessively big. – Oleg G. Sep 23 '20 at 21:00
  • I understand this. GeometryReader is just designed in a way that it takes as much space as it can. Regularly there is a way of avoiding the geometry reader in such situations. With the text in your example, the solution would be to just remove the geometry reader. But I guess your real question needs a different solution. The implementation of your custom view would help. The other solution would be to use anchors for sending the height back from your custom view to the geometry reader (which won't be the beautiful one atm) – Denis Sep 24 '20 at 05:25

2 Answers2

2

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

Andrew Lipscomb
  • 716
  • 5
  • 15
  • Thank you for the explanation, Indeed, I realized iOS 14 is actually a buggy beta released by apple in production For this example, I specified the height of the `GeometryReader`. – Oleg G. Sep 28 '20 at 16:32
  • 1
    There are changes of behaviour in the latest XCode 12 - check the release notes. They ... kind of ... document them. Of course - no documentation in the actual technical docos - because who ever reads that right? – Andrew Lipscomb Sep 29 '20 at 20:43
  • This is nuts So there is no way to not force the geometryreader to have a normal size depending on the text and not the inverse? – Oleg G. Oct 01 '20 at 17:17
1

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/

Kyokook Hwang
  • 2,418
  • 19
  • 36
  • Thank you! I will check that out and come back here if I find a solution!! :) – Oleg G. Sep 23 '20 at 21:00
  • So I read it, but it doesn't really explain why my `GeometryReader` breaks my UI when using the Text alone doesn't. https://swiftui-lab.com/geometryreader-to-the-rescue/ this one explain a little bit more at the end saying that `GeometryReader` is taking all the space available and the child will take what it needs but the `GeometryReader` will not adapt to it. Which I don't get, because SwiftUI is supposed to give the space to the child and adapt the parent around it. And `GeometryReader` breaks this logic. – Oleg G. Sep 23 '20 at 22:37
  • Your first screenshot looks a right result of the first code block. but, to be honest, I don't know exactly what part of code makes it break like the second screenshot. especially, I can't find where `.fixedSize()` is used in your code so can't find out the reason. Could you share your code more that breaks the layout? – Kyokook Hwang Sep 25 '20 at 10:30
  • This is the full code. I don't use `.fixedSize()` here – Oleg G. Sep 25 '20 at 16:11