Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SwiftUI view API patterns

I am writing a SwiftUI framework package where I want to have some APIs that allow presentation of a view. For these views, I always want them presented above the presenting view as a modal sheet view (I want to disallow having these views embedded as a subview in an app’s view).

Apple appears to have very few system APIs like this, but I have found this API – which behaves as I expect:

public func fileImporter(isPresented: Binding<Bool>, allowedContentTypes: [UTType], onCompletion: @escaping (_ result: Result<URL, Error>) -> Void) -> some View

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

https://developer.apple.com/documentation/swiftui/form/fileimporter(ispresented:allowedcontenttypes:allowsmultipleselection:oncompletion:)

Note that Apple has implemented this as a View extension, so you can simply use like so:

Button("Import..") {
    self.showingFileImporter = true
}
.fileImporter(isPresented: $showingFileImporter, allowedContentTypes: [.pdf]) { result in
    // got result
}

So, I’m trying to use this pattern to implement my own API, something like:

func mySomethingSelector(isPresented: Binding<Bool>, completion: @escaping () -> Void) -> some View

However, I’m unsure how to start the implementation. The first thing I noticed is that fileImporter actually returns some View, but this is not the screen that’s actually presented. So, we need to return some kind of wrapper view, that then presents above the wrapper view? (Note that I assume that Apple has actually implemented fileImporter by bridging to UIKit – and possibly out of process. But I just want to use standard SwiftUI for my implementation).

Anyway, hopefully this makes sense. Any guidance appreciated.

>Solution :

A very simple implementation might look like this, using a sheet to display your custom View:

struct ContentView: View {
    @State private var isPresented: Bool = false
    var body: some View {
        Button("Present") {
            isPresented.toggle()
        }
        .mySomethingSelector(isPresented: $isPresented) {
            print("Done")
        }
    }
}

extension View {
    func mySomethingSelector(isPresented: Binding<Bool>, completion: @escaping () -> Void) -> some View {
        self.sheet(isPresented: isPresented, onDismiss: completion) {
            Text("My View")
        }
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading