BLACK FRIDAY SALE: Save big on all my Swift books and bundles! >>

Issue w/ Segmented Picker Data?

Forums > SwiftUI

Hello all, I am relatively new to SwiftUI and I'm trying to work on my first app. I am trying to use a segmented picker to give the user an option of changing between a DayView and a Week View. In each on of those Views, there would be specific user data that whould be shown as a graph. The issue I am having is loading the data. I posted the code below, but from what I can see, the issue comes down to the following:

When the view loads in, it starts with loading the dayView, since the selectedTimeInterval = 0. Which is fine, but then when the users presses on the "Week" in the segmented Picker, the data does not display. This due to the rest of the View loading prior to the .onChange() function from the segmented picker running. Since the .onChange is what puts the call into the viewModel to load the new data, there is no data. You can see this in the print statements if you run the code below.

I would have thought that the view load order would have been

  1. load segmented picker
  2. run the .onChange if the value changed
  3. load the rest of the view

but the order actual is

  1. load segmented picker,
  2. load the rest of the view (graph loads with no data here!!!!!)
  3. run the .onChange if the value has changed.

I am pretty lost so any help would be great! Thank you so much!

import SwiftUI import OrderedCollections

class ViewModel: ObservableObject{ @Published var testDictionary: OrderedDictionary<String, Int> = ["":0]

public func daySelected() {
    testDictionary = ["Day View Data": 100]
}

public func weekSelected() {
    testDictionary = ["Week View Data": 200]
}

}

struct ContentView: View { @State private var selectedTimeInterval = 0 @StateObject private var vm = ViewModel()

var body: some View {
    VStack {
        Picker("Selected Date", selection: $selectedTimeInterval) {
            Text("Day").tag(0)
            Text("Week").tag(1)
        }
        .pickerStyle(SegmentedPickerStyle())
        .onChange(of: selectedTimeInterval) { _ in

            let _ = print("In on change")
            //Logic to handle different presses of the selector
            switch selectedTimeInterval{
            case 0:
                vm.daySelected()
            case 1:
                vm.weekSelected()
            default:
                print("Unknown Selected Case")
            }
        }
        switch selectedTimeInterval {
        case 0:
            let _ = print("In view change")
            Day_View()
        case 1:
            let _ = print("In view change")
            Week_View(inputDictionary: vm.testDictionary)
        default:
            Text("Whoops")
        }
    }
}

}

struct Day_View: View {

var body: some View {
    Text("Day View!")
}

}

struct Week_View: View { @State private var inputDictionary: OrderedDictionary<String,Int>

init(inputDictionary: OrderedDictionary<String,Int>) {
    self.inputDictionary = inputDictionary
}

var body: some View {

    let keys = Array(inputDictionary.keys)
    let values = Array(inputDictionary.values)
    VStack{
        Text(keys[0])
        Text(String(values[0]))
    }
}

}

struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

   

Hacking with Swift is sponsored by RevenueCat

SPONSORED In-app subscriptions are a pain to implement, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app. Oh, and it's free if your app makes less than $10k/mo.

Learn more

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

Reply to this topic…

You need to create an account or log in to reply.

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.