UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Help with Pickers

Forums > SwiftUI

So, I have been refactoring my views, which took a bit to get used to.. Now I have a view that is for Attendance, I have a picker and an enum. What I would like to do, is to be able to select the period of the class being taught, and the cooresponding class being taught, i.e firstPeriod be shown. I think that I would need to keep the picker in the Attendance view, and once the user selects the class period. The selectedPeriod is sent to the roster.swift file where the students in firstPeriod are selected and returned as a view. (keeping the sorting and etc. out of the view).

Am I thinking correctly on this?

Thank you.

Bob

See below for my Attendance View.

import SwiftUI

struct Attendance: View {
    @EnvironmentObject var roster: Roster
    @State var selectedPeriod = Period.firstPeriod

    enum Period: String, CaseIterable, Identifiable {
        var id: String {self.rawValue}
        case firstPeriod
        case secondPeriod
        case thirdPeriod
        case fourthPeriod
        case fifthPeriod
        case sixthPeriod
        case seventhPeriod
        case eighthPeriod
        case flexPeriod
    }
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Select Period")) {
                    Section {
                        Picker("Select Period", selection: $selectedPeriod) {
                            Text("1st").tag(Period.firstPeriod)
                            Text("2nd").tag(Period.secondPeriod)
                            Text("3rd").tag(Period.thirdPeriod)
                            Text("4th").tag(Period.fourthPeriod)
                            Text("5th").tag(Period.fifthPeriod)
                            Text("6th").tag(Period.sixthPeriod)
                            Text("7th").tag(Period.seventhPeriod)
                            Text("8th").tag(Period.eighthPeriod)
                            Text("Flex").tag(Period.flexPeriod)
                        }
                        .pickerStyle(.segmented)
                    }
                }
                Section(header: Text("Period Roster")) {
                    roster.attendance()
                }
            }
        }
        .navigationTitle("Attendance")
        .navigationBarTitleDisplayMode(.inline)
        .navigationViewStyle(.stack) // Makes the view full width
        .accentColor(.blue)
    }
}
struct Attendance_Previews: PreviewProvider {
    static var previews: some View {
        Attendance()
            .previewInterfaceOrientation(.landscapeLeft)
    }
}

2      

Hi blawson3,

There maybe a more efficient way of doing this and I am sure others may provide this however this approach should work for you.

struct RosterView: View {
    // Defines two classes for testing
    private var class1 = [
    "Joe",
    "Tima",
    "Jess"
    ]

    private var class2 = [
    "Taylor",
    "Megan",
    "Olivia",
    "Steph"
    ]

    enum Classes: String {
        case class1
        case class2
    }

    // This it the var where the picker is bound
    @State private var selectedItem = Classes.class1

    // Creates a dictionary of a classess enum to match an array of strings
    private var classToMatch:[Classes:[String]] = [:]

    init() {
        // initialises the classToMatch var with the arrays it requires
        self.classToMatch = [
            Classes.class1: class1,
            Classes.class2: class2
        ]
    }

    var body: some View {
        Picker("Test", selection: $selectedItem) {
            Text("Class 1").tag(Classes.class1)
            Text("Class 2").tag(Classes.class2)
        }

        // Used a force unwrap here as the value should never be nil as it's bound to a picker
        // however you can unwrap if required. What happens here is that the selectedItem is
        // passed to the classToMatch dictionary which then returns all of the students in
        // that array, we then extract one student from the returned array and display it
        // as a text item on the screen.

        ForEach(classToMatch[selectedItem]!, id: \.self) { student in
            Text(student)
        }
    }
}

In order to make this code work for your use case you can swap out Class1 and Class2 in the initialiser for any array of students from your Roster model.

Hope this helps.

2      

Thank you, I will need to look closely at this to make sure that I can understand it, (still a beginner).

Thank you!!

Bob

2      

I am in learning process but will try My best to learn and do it for my https://www.lifepo4golfcartbattery.com/ business

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.