Home > database >  SwiftUI segmented control - how to switch to other segment on tap in first segment?
SwiftUI segmented control - how to switch to other segment on tap in first segment?

Time:09-13

I have a segmentedControl (Picker) with two segments:

struct Container: View {    
    @State private var selectedSegment: Segment = .first
    
    var body: some View {
        VStack {
            Picker("", selection: $selectedSegment) {
                ForEach(Segment.allCases, id: \.self) {
                    Text($0.rawValue)
                }
            }
            .pickerStyle(.segmented)
            .padding()
            Spacer()
            SegmentView(segment: selectedSegment)
            Spacer()
        }
    }
}

struct SegmentView: View {
    var segment: Segment
    
    var body: some View {
        switch segment {
        case .first:
            FirstView()
        case .features:
            FeaturesView()
        }
    }
}

In one of the segments I show a list:

struct FeaturesView: View {
    private var features: [Feature]
        
    var body: some View {
        VStack {
            List(features) { feature in
                FeatureRow(feature: feature)
                    .onTapGesture {
                        // switch to other segment and pass in `feature`
                    }
            }
            .listStyle(PlainListStyle())
        }
    }
}

What I am trying to do is when the user taps on one of the rows in FeaturesView, switch to FirstView and pass in the feature.

How do I do this is SwiftUI ?

Maybe by using a Notification ?

CodePudding user response:

Based on @PtitXav's comments this is what I came up with:

struct Container: View {    
    @State private var selectedSegment: Segment = .first
    @State private var selectedFeature: Feature = Feature()
    
    var body: some View {
        VStack {
            Picker("", selection: $selectedSegment) {
                ForEach(Segment.allCases, id: \.self) {
                    Text($0.rawValue)
                }
            }
            .pickerStyle(.segmented)
            .padding()
            .onChange(of: selectedFeature) { s in
                print(s)
                selectedSegment = .sequence
            }

            Spacer()
            SegmentView(segment: selectedSegment, selectedFeature: $selectedFeature)
            Spacer()
        }
    }
}

struct SegmentView: View {
    @Binding var selectedFeature: Feature

    var segment: Segment
    
    var body: some View {
        switch segment {
        case .first:
            FirstView(selectedFeature: $selectedFeature)
        case .features:
            FeaturesView(selectedFeature: $selectedFeature)
        }
    }
}

struct FeaturesView: View {
    @Binding var selectedFeature: Feature

    private var features: [Feature]
        
    var body: some View {
        VStack {
            List(features) { feature in
                FeatureRow(feature: feature)
                    .onTapGesture {
                        selectedFeature = feature
                    }
            }
            .listStyle(PlainListStyle())
        }
    }
}
  • Related