dimanche 13 novembre 2022

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

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.

Aucun commentaire:

Enregistrer un commentaire