0

I'm wondering how I should change @State property wrapper showErrorAlert in view below

struct SettingsView: View {
@State private var shouldPresent = false
@State var showErrorAlert = false
var body: some View {
    VStack {
        Form {
            Text("Settings")
                .font(.title)
            Button("Import source data") {
                self.shouldPresent.toggle()
            }
            .sheet(isPresented: $shouldPresent) {
                DocumentPicker()
            }
            Button("Show error alert") {
                self.showErrorAlert.toggle()
            }
            .alert(isPresented: $showErrorAlert, content: {
                Alert(title: Text("Error"))
            })
        }
    }
}
}

from DocumentPicker struct code in case that reading of selected file fails.

struct DocumentPicker: UIViewControllerRepresentable {

func makeCoordinator() -> DocumentPicker.Coordinator {
    return DocumentPicker.Coordinator(parent: self)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController {
    let picker = UIDocumentPickerViewController(documentTypes: [String(kUTTypeJSON)], in: .import)
    picker.allowsMultipleSelection = false
    picker.delegate = context.coordinator
    return picker
}

func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<DocumentPicker>) {
}

class Coordinator: NSObject, UIDocumentPickerDelegate {

    var myParent: DocumentPicker
    init(parent: DocumentPicker) {
        myParent = parent
    }

    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        let fileURL = urls.first!
        do {
            let origFile = try String(contentsOf: fileURL)
            //File processing will be here
        } catch let error {
            print(error)
        }
    }
}
}

I mean how to set property wrapper value to true to show the alert. Should I rather use @ObservedObject or @EnvironmentObject instead? Thanks.

Dawy
  • 770
  • 6
  • 23

1 Answers1

2

To change the wrapper value in your DocumentPicker struct you can define a @Binding variable and pass your value to it, this toggle your variable on your parent view, but before showing the alert you need to dismiss the DocumentPicker

Mac3n
  • 4,189
  • 3
  • 16
  • 29
  • If I declare @Binding var isPresented = false in DocumentPicker struct I get error "Argument labels '(wrappedValue:)' do not match any available overloads" – Dawy Feb 07 '20 at 20:25
  • There is no need to set value for your @Binding variable, you should just define `@Binding var isPresented: Bool` – Mac3n Feb 07 '20 at 20:26
  • Right. And how I could to set isPresented variable within func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) to true to make alert shown? Compiler says "Instance member 'isPresented' of type 'DocumentPicker' cannot be used on instance of nested type 'DocumentPicker.Coordinator'" if I try isPresented = true in do-catch. – Dawy Feb 07 '20 at 20:37
  • calling `myParent.isPresented = true` should work in a catch block – Mac3n Feb 07 '20 at 20:50