Notice: Undefined index: ios-swiftui in /var/sites/ on line 130
Creating views in a loop - a free tutorial

NEW: Join my free 100 Days of SwiftUI challenge today! >>

Creating views in a loop

Paul Hudson    @twostraws   

Fully updated for Xcode 11 GM

It’s common to want to create several SwiftUI views inside a loop. For example, we might want to loop over an array of names and have each one be a text view, or loop over an array of menu items and have each one be shown as an image.

SwiftUI gives us a dedicated view type for this purpose, called ForEach. This can loop over arrays and ranges, creating as many views as needed. Even better, ForEach doesn’t get hit by the 10-view limit that would affect us if we had typed the views by hand.

ForEach will run a closure once for every item it loops over, passing in the current loop item. For example, if we looped from 0 to 100 it would pass in 0, then 1, then 2, and so on.

For example, this creates a form with 100 rows:

Form {
    ForEach(0 ..< 100) { number in
        Text("Row \(number)")

Because ForEach passes in a closure, we can use shorthand syntax for the parameter name, like this:

Form {
    ForEach(0 ..< 100) {
        Text("Row \($0)")

ForEach is particularly useful when working with SwiftUI’s Picker view, which lets us show various options for users to select from.

To demonstrate this, we’re going to define a view that:

  1. Has an array of possible student names.
  2. Has an @State property storing the currently selected student.
  3. Creates a Picker view asking users to select their favorite, using a two-way binding to the @State property.
  4. Uses ForEach to loop over all possible student names, turning them into a text view.

Here’s the code for that:

struct ContentView: View {
    let students = ["Harry", "Hermione", "Ron"]
    @State private var selectedStudent = "Harry"

    var body: some View {
        Picker("Select your student", selection: $selectedStudent) {
            ForEach(0 ..< students.count) {

There’s not a lot of code in there, but it’s worth clarifying a few things:

  1. The students array doesn’t need to be marked with @State because it’s a constant; it isn’t going to change.
  2. The selectedStudent property starts with the value “Harry” but can change, which is why it’s marked with @State.
  3. The Picker has a label, “Select your student”, which tells users what it does and also provides something descriptive for screen readers to read aloud.
  4. The Picker has a two-way binding to selectedStudent, which means it will start showing a selection of 0 but update the property as the user moves the picker.
  5. Inside the ForEach we count from 0 up to (but excluding) the number of students in our array.
  6. For each student we create one text view, showing that student’s name.

We’ll look at other ways to use ForEach in the future, but that’s enough for this project.

This is the final part of the overview for this project, so it’s almost time to get started with the real code. If you want to save the examples you’ve programmed you should copy your project directory somewhere else.

When you’re ready, put ContentView.swift back to the way it started when you first made the project, so we have a clean slate to work from:

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello World")

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {

LEARN SWIFTUI FOR FREE I have a massive, free SwiftUI video collection on YouTube teaching you how to build complete apps with SwiftUI – check it out!

Buy Testing Swift Buy Practical iOS 12 Buy Pro Swift Buy Swift Design Patterns Buy Swift Coding Challenges Buy Server-Side Swift (Vapor Edition) Buy Server-Side Swift (Kitura Edition) Buy Hacking with macOS Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with Swift Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!