2

I have EditNoteHost view which displays NoteView or EditNote depending on editMode environment variable. Aslo Cancel button is displayed in edit mode:


struct EditNoteHost: View {
    @EnvironmentObject var modelData: ModelData
    @Environment(\.editMode) var editMode
    
    @State private var draftNote = Note.default
    
    var body: some View {
        VStack(alignment: .leading, spacing: 20) {
            
            HStack {
                if editMode?.wrappedValue == .active {
                    Button("Cancel") {
                        draftNote = modelData.selectedNote
                        editMode?.animation().wrappedValue = .inactive
                    }
                }
                Spacer()
                EditButton()
            }
            
            if editMode?.wrappedValue == .inactive {
                NoteView(note: modelData.selectedNote)
            } else {
                EditNote(note: $draftNote)
                    .onAppear {
                        draftNote = modelData.selectedNote
                    }
                    .onDisappear {
                        modelData.selectedNote = draftNote
                    }
            }
        }
        .padding()
    }
}

struct EditNoteHost_Previews: PreviewProvider {
    static var previews: some View {
        EditNoteHost()
            .environmentObject(ModelData())
    }
}

This code works fine.

Now I want to use EditNoteHost in NavigationLink and start it in edit mode:

NavigationLink(destination: EditNoteHost().environment(\.editMode, Binding.constant(EditMode.active)).environmentObject(modelData)) {
                    Image(systemName: "plus")
                }

This part of code opens EditNoteHost in edit mode if click +. However, Done and Cancel buttons do nothing when tap.

How can I fix this?

Screenshot

1
  • Please provide standalone minimal reproducible example. Commented Jan 28, 2021 at 12:52

1 Answer 1

2

You are setting editMode using .constant(EditMode.active), it will remain active. So do not set the environment for editMode; instead use:

NavigationLink(destination: EditNoteHost()) {
    Image(systemName: "plus")
}

and in EditNoteHost, use:

.onAppear() {
    editMode?.animation().wrappedValue = .active
}
Sign up to request clarification or add additional context in comments.

5 Comments

EditNoteHost().environment(\.editMode, Binding.constant(EditMode.active) means that editMode environment variable will have active state. This is exactly what I need.EditButton() should change state of environment variable but nothing happens
yes .constants means that it's always gonna be .active try to avoid using .constant. I edited my answer, let me know if it solves your problem!
@ S_dnomseD thank you for answer. Unfortunately this does not solve my problem. This will work fine when I create notes. In this case I need edit mode. However, when I select existing notes I need to use EditNoteHost in inactive mode(
In that case you can pass a boolean value to EditNoteHost, and in onAppear use: if editing { editMode?.animation().wrappedValue = .active }else { editMode?.animation().wrappedValue = .inactive }. So when you need it active pass EditNoteHost(editing: true), inactive EditNoteHost(editing: false).
S_dnomseD this looks like a solution. Thank you!

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.