0

I need to present 3 different Views.

   AddListView
   ChangeColor
   EditListView

They take different paramater. AddListView does not have parameter while ChangeColor and EditListView takes Color and NSManagedObject respectively. However for the sake of simplicity, EditListView's paramter is integer in this example.

I am using .fullScreenCover(item: <#T##Binding<Identifiable?>#>, content: <#T##(Identifiable) -> View#>) for presenting them.

.fullScreenCover(item: $presentedViewType) { type in
    if type == .AddListView {
        AddListView()
    }
    else if type == .EditListView {
        if let index = selectedIndex {
            EditListView(index: index)
        }
    }
    
    else if type == .ChangeColor {
        if let color = selectedColor {
            ColorView(color: color)
        }
    }
}

selectedIndex and selectedColor is nil even though I initialize them before initializing presentedViewType. And hence, an EmptyView is presented.

This is the project.

enum PresentedViewType: Identifiable {
    case AddListView
    case ChangeColor
    case EditListView
    
    var id: Int {
        return hashValue
    }
}


struct ContentView: View {
    
    @State var presentedViewType: PresentedViewType?
    
    @State var selectedColor: Color?
    
    @State var selectedIndex: Int?
    
    var body: some View {
        NavigationView {
            List {
                
                Section {
                    NavigationLink(destination: Text("All")) {
                        Text("All")
                    }
                    .background(Color.blue)
                    .contextMenu {
                        Button(action: {
                            selectedColor = .blue
                            presentedViewType = .ChangeColor
                        }) {
                            Label("Change Color", systemImage: "paintbrush.pointed.fill")
                        }
                    }
                }
                
                ForEach(0..<10) { index in
                    NavigationLink(destination: Text("Row Details \(index)")) {
                        Text("Row \(index)")
                    }
                    .contextMenu {
                        Button(action: {
                            selectedIndex = index
                            presentedViewType = .EditListView
                        }) {
                            Label("Edit", systemImage: "square.and.pencil")
                        }
                    }
                }
                
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        presentedViewType = .AddListView
                    }) {
                        Label("Add", systemImage: "plus")
                    }
                }
            }
            .fullScreenCover(item: $presentedViewType) { type in
                if type == .AddListView {
                    AddListView()
                }
                else if type == .EditListView {
                    if let index = selectedIndex {
                        EditListView(index: index)
                    }
                }
                
                else if type == .ChangeColor {
                    if let color = selectedColor {
                        ColorView(color: color)
                    }
                }
            }
        }
    }
}



struct ColorView: View {
    @Environment(\.presentationMode) var presentationMode
    
    @State var color: Color
    
    var body: some View {
        NavigationView {
            Text("Color View")
                .background(color)
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {
                            presentationMode.wrappedValue.dismiss()
                        }) {
                            HStack {
                                Image(systemName: "xmark")
                            }
                        }
                    }
                }
        }
    }
}



struct  AddListView: View {
    @Environment(\.presentationMode) var presentationMode
    @State var text: String = ""
    
    var body: some View {
        NavigationView {
            TextField("", text: $text)
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {
                            presentationMode.wrappedValue.dismiss()
                        }) {
                            HStack {
                                Image(systemName: "xmark")
                            }
                        }
                    }
                }
        }
    }
}



struct  EditListView: View {
    @Environment(\.presentationMode) var presentationMode
    
    @State var index: Int
    
    var body: some View {
        NavigationView {
            Text("Row \(index)")
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {
                            presentationMode.wrappedValue.dismiss()
                        }) {
                            HStack {
                                Image(systemName: "xmark")
                            }
                        }
                    }
                }
        }
    }
}

I have to mention that they do not have fixed value. They have different value depending on which row you need to edit.

How to pass selectedIndex and selectedColor to EditListView and ColorView respectively?

Update

EditListView takes only selectedIndex while ColorView takes only selectedColor

1 Answer 1

3

You need to have @Binding properties inside EditListView and ColorView

struct EditListView: View {

    @Binding var selectedIndex: Int?

    // rest of view implementation
}

struct ColorView: View {

    @Binding var selectedIndex: Int?

    // rest of view implementation
}

and then pass the binding in the initialisers

.fullScreenCover(item: $presentedViewType) { type in
    if type == .AddListView {
        AddListView()
    } else if type == .EditListView {
        EditListView(index: $selectedIndex)
    } else if type == .ChangeColor {
        ColorView(color: $selectedColor)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.