'The TextFields on my SwiftUI macOS project are making my window height too tall

I have a multiplatform SwiftUI project and I noticed on the macOS side that some of the views make my window too tall and I, the user, can't make it shorter. I noticed this with two particular views and so created a sample project containing a simplified version to duplicate this issue and figure it out. I was able to duplicate the issue and, through commenting out lines and running it, found the source seems to be the TextField itself. Is there anyway to make the window shorter as is? Is there something I can use instead of a TextField to fix this? Or am I stuck with this until the framework is updated? Figured I'd ask here in case anyone has any insight.

For your ease at replicating I'll include the code and then, below, screenshots explaining my issue. Thanks

Main ContentView:

struct ContentView: View {
var body: some View {
    TabView {
        ExampleViewOne()
            .tabItem {
                Label("Example One", image: "one")
            }
            .tag("one")
        ExampleViewTwo()
            .tabItem {
                Label("Example Two", image: "two")
            }
            .tag("two")
    }
    .background(Color.green)
}
}

Example One struct for the first tab:

struct ExampleViewOne: View {

// Editable Fields
@State var aString:String = "name"
@State var aBoolean:Bool = false

var body: some View {
    VStack(alignment: .center) {
        Form {
            Text("Hello Everyone!")
                .italic()
                .frame(maxWidth: .infinity)
                .multilineTextAlignment(.center)
        
            Button(action: {
                print("A Button")
            }, label: {
                HStack(spacing: 10) {
                    Text("A Button")
                }
                .frame(maxWidth: .infinity)
            })

            TextField("Name:", text: $aString, prompt: Text("Nickname"))
//                TextField("Username:", text: $aString, prompt: Text("root"))
//                TextField("Password:", text: $aString, prompt: Text("********"))
//                TextField("I.P. Address:", text: $aString, prompt: Text("XXX.XXX.X.XXX"))

            Button(action: {
                print("Another button")
            }) {
                HStack(spacing: 10) {
                    Image(systemName: "questionmark")
                    Text("Another button")
                    Image(systemName: "questionmark")
                }
                .frame(maxWidth: .infinity)
            }

            Divider()

            Toggle(isOn: $aBoolean, label: {
                Text("This is the label of this switch")
            })
        }
        .background(Color.purple)
            
        Spacer()
            .background(Color.red)
        
        HStack(spacing:10) {
            Button(action: {
                print("Delete")
            }) {
                HStack(spacing: 10) {
                    Image(systemName: "trash.fill")
                    Text("Delete (⌘ d)")
                }
                .frame(maxWidth: .infinity)
            }
            .keyboardShortcut("d", modifiers: .command)
            
            Button(action: {
                print("Save")
            }) {
                HStack(spacing: 10) {
                    Image(systemName: "checkmark")
                    Text("Save")
                }
                .frame(maxWidth: .infinity)
            }
            .keyboardShortcut("s", modifiers: .command)
        }
        .background(Color.blue)
    }
    .padding()
    .background(Color.black)
}
}

Example Two struct for the second tab

struct ExampleViewTwo: View {

// Editable Fields
@State var aString:String = "name"
@State var aBoolean:Bool = false

let theExamples = ["example one", "example two", "example another"]

var body: some View {
    VStack(alignment: .center) {
        Form {
            TextField("Display Name:", text: $aString, prompt: Text("Name"))
//                TextField("Directory (Folder) Name:", text: $aString, prompt: Text("Directory Name"))
            
            ScrollView {
                Text("These are the examples.")
                ForEach(theExamples, id:\.self) { number in
                    Text(number)
                }
            }
        }
        .background(Color.purple)
        
        Spacer()
            .background(Color.red)
        
        HStack(spacing:10) {
            Button(action: {
                print("Delete")
            }) {
                HStack(spacing: 10) {
                    Image(systemName: "trash.fill")
                    Text("Delete (⌘ d)")
                }
                .frame(maxWidth: .infinity)
            }
            .keyboardShortcut("d", modifiers: .command)
            
            Button(action: {
                print("Save")
            }) {
                HStack(spacing: 10) {
                    Image(systemName: "checkmark")
                    Text("Save")
                }
                .frame(maxWidth: .infinity)
            }
            .keyboardShortcut("s", modifiers: .command)
        }
        .background(Color.blue)
    }
    .padding()
    .background(Color.black)
}
}

Explanation:

I set different background colors to each view, to tell them apart, and then played with the spacers before commenting out the code in the top (purple) view and slowly bringing it back until the height was restricted again.

The spacer background color isn't shown on either tab but it is used on Example One. For Example One the views are centered vertically if the spacer isn't there yet the height isn't affected. On Example Two the height also stays the same regardless of the spacer's presence but the space itself is taken up by the purple view instead.

The first tab with the spacer included is laid out properly but I want the black space between the two smaller: The first tab with the spacer included is laid out properly but I want the black space between the two smaller. Without the spacer the views are centered but the height is still unable to be shortened by the user: Without the spacer the views are centered but the height is still unable to be shortened by the user. The second tab looks the same regardless whether there's a spacer or not with the purple view taking up the space that is somehow required: The second tab looks the same regardless whether there's a spacer or not with the purple view taking up the space that is somehow required.

After commenting out the code and bringing it back again I realized the culprit was the TextField as without them the window could be as small as I wanted it. With one TextField uncommented the height was restricted. With each additional TextField uncommented the height became taller and taller.

With no TextField in the view I could make the Window however small I wanted: With no TextField in the view I could make the Window however small I wanted. As soon as I added a TextField back the height was restricted: As soon as I added a TextField back the height was restricted. With each additional TextField added the height needed became larger and thus the empty black space was larger. I can't make the Window smaller than this: With each additional TextField added the height needed became larger and thus the empty black space was larger. I can't make the Window smaller than this. The same could be said for the second example window. No TextFields means I could make the Window really short. The uncommenting of a TextField made the height increase without me making it smaller. The additional TextFields makes it taller and the purple space larger: The same could be said for the second example window. No TextFields means I could make the Window really short. The uncommenting of a TextField made the height increase without me making it smaller. The additional TextFields makes it taller and the purple space larger.

Is there anyway to allow me to make this Window smaller in the presence of the TextFields?

My other views don't seem to have this problem but they're contained within a ScrollView. I could embed these too but now I'm really curious what's causing it.

Thanks for any help.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source