Learn Courses My Dashboard

Display array horizontally left-to-right

I would like to display the contents of an array horizontally left-to-right, breaking onto new lines if required.

    var numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]

    var body: some View {
        ScrollView {
            ForEach(0..<numbers.count, id: \.self) { index in
                Text(numbers[index])
            }
        }
    }

It seems like it should be easy, but I just can’t figure it out.

Any suggestions?

use

ScrollView(.horizontal, showsIndicators: false)  {
...
}

I appreciate the feedback.

Unfortunately it didn’t have the intended outcome. It still aligns the strings as if in a VStack, now aligned to the left margin.

Ultimately, I would like the strings to be displayed sequentially next to each other, with line breaks–just like this sentence.

one two three four five six seven eight nine ten

@CeilingTiles

Hi Brent,

The thing is with an array is that you need to concatenate the elements of the array into a single string so that it can be treated as though it is a sentence. In that way you can wrap it and format it so that it makes sense.

Consider this:

struct ContentView: View {
    var numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen"]
    @State private var concatenatedString = ""

    var body: some View {
        ScrollView {

            HStack {
                Text(concatenatedString)
                    .multilineTextAlignment(.leading)
            }
            .padding(.horizontal)  // Just to get it away from the edge of the screen
        }
        .onAppear {
            concatenatedString = numbers.joined(separator: " ")
        }
    }
}

When you loop through the array and place a Text() element in the View, say, in a HStack like this:

HStack(spacing: 2) {
    ForEach(0..<numbers.count, id: \.self) { index in
        Text(numbers[index])
    }
}
.padding(.horizontal)  // Just to get it away from the edge of the screen

What you are doing is placing each element into its own Text View container and it occupies the space available. If that horizontal space is less than it needs to display the letters in a line, it will squish them so that the letters spill vertically as in this screenshot.

Sorry I did not checked it… but I agree with Chris:

If you want a scroll view and foreach, it also possible just add the HStack

    @State var numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen"]

// inside your view:

ScrollView(.horizontal, showsIndicators: true, content: {
                    HStack {
                        ForEach(numbers, id: \.self) { num in
                            Text(num)
                        }
                    }
                    
                })

this is the output:

you can scroll it

First of all: thank you both for your responses. At this point I feel like I’m mostly done with the tutorials and the real reason I remain a subscriber is to be able to connect with people like you. Thank you.

Secondly: what an elegant solution. It seems so obvious once you lay it out like that.

But here’s the kicker: this was the first question I’ve ever asked on this forum and I simplified it as I thought it was the right thing to do. Now I don’t think so…

Ideally the elements in the array aren’t just strings, I was intending on using them as buttons. I chose to format them as strings with an .onTapGesture instead of making them buttons because I wanted the variable widths.

Ultimately, I’m trying to create something like this page where people can select their interests (this screenshot is from TikTok).

1 Like

@CeilingTiles

In that case you need to use something like a LazyHGrid which will allow you to have variable width content.

@CeilingTiles You should google “swiftui flow layout”. That’s what you’re trying to accomplish is called.

1 Like

Amazing. Thank you.