With Swiftui how we can create user form

2020-07-26 14:13发布

问题:

I want to create a form in which all textfield need to start from the same alignment, like in below image it does not start from the same alignment. First name, last name and Phone number all textFields are not aligned properly in a single vertical line.

VStack(){
        HStack(){
            Text("First Name")
            TextField("First name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
        }
        HStack(){
            Text("Last Name")
            TextField("Last Name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
        }
        HStack(){
            Text("Phone number")
            TextField("Phone number", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
        }
        Spacer()
    }.padding(10)

回答1:

You can use GeometryReader to access device size and frame to set fixed width for Texts. For example:

GeometryReader { geometry in
    VStack(spacing: 10) {
        HStack {
            Text("First Name").frame(width: geometry.size.width / 3)
            TextField("First name", text: self.$name).textFieldStyle(RoundedBorderTextFieldStyle())
        }
        HStack {
            Text("Last Name").frame(width: geometry.size.width / 3)
            TextField("Last Name", text: self.$name).textFieldStyle(RoundedBorderTextFieldStyle())
        }
        HStack{
            Text("Phone number").frame(width: geometry.size.width / 3)
            TextField("Phone number", text: self.$name).textFieldStyle(RoundedBorderTextFieldStyle())
        }
        Spacer()
    }.padding(10)
}     


回答2:

This will align your TextFields:

VStack {
    HStack {
        HStack {
            Text("First Name")
            Spacer()
        }
        TextField("First name", text: $name)
            .textFieldStyle(RoundedBorderTextFieldStyle())
    }
    HStack {
        HStack {
            Text("Last Name")
            Spacer()
        }
        TextField("Last Name", text: $name)
            .textFieldStyle(RoundedBorderTextFieldStyle())
    }
    HStack {
        HStack {
            Text("Phone number")
            Spacer()
        }
        TextField("Phone number", text: $name)
            .textFieldStyle(RoundedBorderTextFieldStyle())
    }
    Spacer()
}   .padding(10) 


回答3:

        VStack{
            HStack(){
                Text("First Name").frame(width: 120, alignment: .leading)
                TextField("First name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            HStack(){
                Text("Last Name").frame(width: 120, alignment: .leading)
                TextField("Last Name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            HStack{
                Text("Phone number").frame(width: 120, alignment: .leading)
                TextField("Phone number", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            Spacer()
        }.padding(10)

or more flexible solution

struct TestView: View {
    @State var name = ""
    @State var width: CGFloat = 0

    struct Label: ViewModifier {
        @Binding var width: CGFloat

        func getWidth(content: Content, proxy: GeometryProxy) -> some View {
            if proxy.size.width > width {
                RunLoop.main.perform {
                    self.width = proxy.size.width
                }
            }
            return content
        }

        func body(content: Content) -> some View {
            content.overlay(GeometryReader { proxy in
                self.getWidth(content: content, proxy: proxy)
            }).frame(minWidth: self.width, alignment: .leading)
        }
    }

    var body: some View {
        VStack(alignment: .center){
            HStack(){
                Text("First Name").modifier(Label(width: $width))
                TextField("First name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            HStack(){
                Text("Last Name").modifier(Label(width: $width))
                TextField("Last Name", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
            }
            HStack{
                Text("Phone numbe").modifier(Label(width: $width))
                TextField("Phone number", text: $name).textFieldStyle(RoundedBorderTextFieldStyle())
            }

            Spacer()
        }.padding(10)
    }
}