Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI TextField takes max width

I have a navigation list with each list item being in this format:

HStack {
        TextField("Insert something here.",text: self.$userData.pages[i].title)
            .border(Color.blue)
        Spacer()
    }

This results in the following view:

The touchable area is highlighted by the blue border and it takes the whole width of the row

The problem with this is that despite the list item being a navigation link, the user clicking anywhere along the item will result in them editing the text content. What I would prefer is a TextField that has the same width as a Text:

The blue border wraps the text instead of taking the max width

So if the user clicks outside the TextField, the navigation works, but if they click on the text, it will let them edit the text. (The above view is with Text field).

Apologies if I've asked an unclear or bad question. I'm new to Stack Overflow and SwiftUI.

Edit:

I've tried using the fixedSize modifier, and the TextField correctly wraps my Text, but now the Navigation Link doesn't work (i.e. clicking on it just doesn't navigate). This is my full code:

NavigationLink(destination: PageView(page: self.userData.pages[i])) {
                        HStack {
                            Button(action: {}){
                                TextField(" ", text: self.$userData.pages[i].title)
                                .fixedSize()

                            }
                            .buttonStyle(MyButtonStyle())
                            .border(Color.blue)
                            Spacer()
                        }
                    }
like image 683
user4500882 Avatar asked Jun 10 '20 17:06

user4500882


People also ask

How do I make text full width in SwiftUI?

How to make a SwiftUI view to fill its container width or height. To make a SwiftUI view take all available width, we use . frame() modifier with maxWidth and maxHeight set to . infinity .

What is TextField SwiftUI?

A TextField is a type of control that shows an editable text interface. In SwiftUI, a TextField typically requires a placeholder text which acts similar to a hint, and a State variable that will accept the input from the user (which is usually a Text value).


1 Answers

No need to apologize, your question is clear. You can do this by using fixedSize()

so your code should be like this

HStack {
        TextField("Insert something here.",text: self.$userData.pages[i].title)
            .border(Color.blue)
            .fixedSize()
        Spacer()
    }

You can further specify how would you like the stretch to be, either vertical or horizontal or even both by passing parameters like so .fixedSize(horizontal: true, vertical: false)

UPDATED ANSWER TO MATCH YOUR NEW REQUIREMENTS

import SwiftUI

struct StackOverflow5: View {
    @State var text: String = ""
    @State var selection: Int? = nil

    var body: some View {
        NavigationView {
            ZStack {
                NavigationLink(destination: Page2(), tag: 1, selection:self.$selection) {
                    Color.clear
                        .onTapGesture {
                            self.selection = 1
                        }
                }


                TextField("Text", text: self.$text)
                    .fixedSize()
            }
        }
    }
}

struct StackOverflow5_Previews: PreviewProvider {
    static var previews: some View {
        StackOverflow5()
    }
}

struct Page2: View {
    var body: some View {
        Text("Page2")
    }
}

We used a ZStack here to separate between our TextField and our NavigationLink so they can be interacted with separately.

Note the use of Color.clear before our TextField and this is on purpose so that our TextField has interaction priority. Also we used Color.clear because it will stretch as a background and it's clear so it's not visible.

Obviously I hard coded 1 here but this can be from List or a ForEach

Additionally, if you don't want to use selection and tag you can do something like this

...
@State var isActive: Bool = false
...
NavigationLink(destination: Page2(), isActive: self.$isActive) {
     Color.clear
          .onTapGesture {
               self.isActive.toggle()
          }
}
....
like image 50
Muhand Jumah Avatar answered Sep 22 '22 06:09

Muhand Jumah