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

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() } }

1      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.