Search code examples
swiftswiftuitoggle

How do I fix Toggle Positioning in SwiftUI


I'm currently in the process of learning Swift and I've run into something strange. My intention for this example is for the two text editors and toggle to be horizontally aligned, however in the preview, the toggle appears much lower than the first two controls.

I figure the toggle label is getting too close to the second text editor, but I can't figure out how to have the label make better use of the screen real estate so they all line up.

Code and Screenshot of the preview follow:


import SwiftUI

struct PlayerEditCell: View {

@State private var fullText: String = "Name"
@State private var quantity: String = "5"
@State private var active: Bool = true

var body: some View {
    HStack() {
        TextEditor(text: $fullText)
            .padding(.leading)
            .frame(width: 160.0)
            .font(.custom("HelveticaNeue", size: 20))
        TextEditor(text: $quantity)
            .frame(width: 20.0)
            .font(.custom("HelveticaNeue", size: 20))
        Toggle(isOn: $active)
        {
            Text("Active")
        }
        .padding(.trailing)
    }
}
}

struct PlayerEDitCell_Previews: PreviewProvider {
    static var previews: some View {
        PlayerEditCell()
    }
}

Preview Screenshot


Solution

  • They are actually perfectly aligned - the Toggle is aligned with the centre of the TextEditors. You haven't constrained the height of the TextEditors, so they fill the whole view.

    Put a .border(.red) modifier on the TextEditors and you'll see this.

    You could just use a .top alignment on the HStack

    If your aim is to get a toolbar type effect along the top of the screen, you can do something like this:

    var body: some View {
          VStack{
             HStack(alignment: .center){
                TextEditor(text: $fullText)
                   .padding(.leading)
                   .frame(width: 160.0)
                   .lineLimit(1)
                TextEditor(text: $quantity)
                   .frame(width: 20.0)
                   .lineLimit(1)     
                Spacer()
                Toggle(isOn: $active)
                {
                   Text("Active")
                }
                .padding(.trailing)
                .frame(width: 200)
             }
             .font(.custom("HelveticaNeue", size: 20))
             .frame(height: 60)
             Spacer()
          }
       }