Curious Jorge
Curious Jorge

Reputation: 1269

How do we control the automatic dividers in SwiftUI forms?

I'm curious, is there a way we can control (or make sense of) the automatic dividers that swiftui puts between items?

Here's some code showing strange behaviour (on iOS simulator):

struct FormSeparator: View {
    @State private var passwd = ""
    var body: some View {
        Form {
            ZStack(alignment: .trailing) {
                TextField("password", text:$passwd)
                Text("8 chars min")
                    .font(.caption)
                    .foregroundColor(.secondary)
            }
            TextField("confirm", text:$passwd)
        }
    }
}

Here's the result:

example of strange divider

This seems to have something to do with the Text that I'm stacking on top of the password field. If I change it the Text to Image(systemName: "lock") then everything works as you'd expect:

example of normal divider

Mind you, I don't even understand why it doesn't extend all the way across the form in that case. Presumably this is deliberate, has anyone seen anything official about this situation? Do we know how to control this?

Upvotes: 3

Views: 1078

Answers (3)

Daniel Wallman
Daniel Wallman

Reputation: 418

I solved my problem by adding .listRowSeparator(.visible)

Upvotes: 2

Offbeat Upbeat
Offbeat Upbeat

Reputation: 646

There is a lazy workaround if you want to support iOS 15. You can add a Text("") element at the start of the HStack.

The Form draws the dividers in alignment with the first Text element. That's why the divider starts halfway over when the "8 chars min" text is shown, but not when the lock image is shown instead. (why you be like this siwftui?)

This workaround is unacceptable if your rows will be above/below other textfields though, as it will appear with slightly more leading whitespace.

Upvotes: 0

Nirav D
Nirav D

Reputation: 72410

In iOS 16, List/Form row separator insets automatically and aligns with the text. In iOS 16, we got two new alignments, listRowSeparatorLeading and listRowSeparatorTrailing, to work with alignmentGuide(_:computeValue:).

ZStack(alignment: .trailing) {
    TextField("password", text:$passwd)
    Text("8 chars min")
        .font(.caption)
        .foregroundColor(.secondary)
}
.alignmentGuide(.listRowSeparatorLeading) { viewDimensions in
    return 0
}

Upvotes: 7

Related Questions