Dan
Dan

Reputation: 85

Cycle through a Picker selection from Array

I'm quite new to Swift and coding in general so apologies if this is a super simple question.

I'm trying to add a button either side of a Picker to allow the user to move up/down the selections within the Picker (my Picker is populated from an Array) - I'm using this selection in another part of my App.

The code below works but only updates the example Text, but it does not update the selection: within the pickerto update correctly.

Any ideas what I'm doing wrong?

import SwiftUI

struct ContentView: View {
    
    let myArray = ["Period 1", "Period 2", "Period 3", "Period 4", "Period 5", "Period 6", "Period 7", "Period 8", "Period 9", "Period 10", "Period 11", "Period 12", "Period 13"]
    @State var currentIndex = 0
    
    var body: some View {
        VStack(spacing: 20) {
            
            HStack {
                Button(action: {
                    if currentIndex == 0 {
                    } else {
                        currentIndex -= 1
                    }
                }) {
                    Image(systemName: "chevron.left.circle")
                        .imageScale(.large)
                }
                .padding(2)
                .frame(maxWidth: .infinity, alignment: .leading)
                
                Picker(selection: $currentIndex, label: Text("Picker")) {
                    ForEach(myArray, id: \.self) {
                        Text($0)
                    }
                }
                
                Button(action: {
                    if currentIndex == 12 {
                    } else {
                        currentIndex += 1
                    }
                }) {
                    Image(systemName: "chevron.right.circle")
                        .imageScale(.large)
                }
                .padding(2)
                .frame(maxWidth: .infinity, alignment: .trailing)
                
            }
            .padding()
            
            Text("\(myArray[currentIndex])")

        }
    }
    
}

'''

Upvotes: 7

Views: 3536

Answers (1)

Joakim Danielson
Joakim Danielson

Reputation: 52013

The problem here is that you are programmatically updating your State variable currentIndex but you are not modifying the array selection. To make this work you need to iterate the array over the indices and not the elements so change the Picker code to this

Picker(selection: $currentIndex, label: Text("Picker")) {
    ForEach(myArray.indices) { index in
        Text(myArray[index])
    }
}

Here each item in the picker automatically gets the id of the raw value of index which matches with currentIndex which makes this work.

To work directly with the elements of the array here is an alternative solution where a new State variable is added to hold the selected string.

@State var currentSelection = ""
@State var currentIndex = 0 {
    didSet {
        currentSelection = myArray[currentIndex]
    }
}

The picker code gets changed to

Picker(selection: $currentSelection, label: Text("Picker")) {
    ForEach(myArray, id: \.self) { period in
        Text(period)
    }
}

but the rest of the code is the same since the buttons are still using currentIndex

Upvotes: 9

Related Questions