4
votes

I'd like to create a UI similar to Apple's in Game Center Settings, where there is a tappable link at the end of text:

enter image description here

I'm using SwiftUI. I tried to combine Text and Button in several ways:

Form {
    Text("A social gaming service that lets you interact with friends, track and compare scores and achievements, challenge other players, and compete in mulitplayer games.")
    Button("See how your data is managed...", action: {})

    Button(action: {}, label: {
        Text("A social gaming service that lets you interact with friends, track and compare scores and achievements, challenge other players, and compete in mulitplayer games.").foregroundColor(.black)
        Text("See how your data is managed...")
    })

    Group {
        Text("A social gaming service that lets you interact with friends, track and compare scores and achievements, challenge other players, and compete in mulitplayer games.")
        Button("See how your data is managed...", action: {})
    }

    HStack {
        Text("A social gaming service that lets you interact with friends, track and compare scores and achievements, challenge other players, and compete in mulitplayer games.")
        Button("See how your data is managed...", action: {})
    }
}

But none of these combinations worked:

enter image description here

I would ideally like to avoid using an NSAttributedString, as I want to use SwiftUI components, and only want the blue portion to be tappable.

How do I append a Button to Text so that it's text is aligned to the baseline of the text?

1

1 Answers

2
votes

It's unlikely that this type of layout will be available in SwiftUI anytime soon. The major complexity comes from the fact that the Button text must have some knowledge about (A) the frame of the Text block (e.g. to know where to place overflowing content like the word "data" in the original example), (B) to align the Button's first baseline to the Text's last baseline, and (C) to align the Button's leading edge to the exact end of Text on the last line (e.g. it can't just to the right of the frame, otherwise you'll get HStack behavior).

One workaround is to follow a different pattern (i.e. the one in the Safari Settings) where the components are vertically placed:

enter image description here

This is a far easier layout to achieve in SwiftUI:

Section(footer:
    VStack(alignment: .leading) {
        Text("Allow websites to check if Apple Pay is enabled and if you have an Apple Card account.")
        Button("About Safari & Privacy...", action: {})
}) {
    EmptyView()
}