can i define something like func myRender() -> Image | Text
(union-types) ?
hi, all. i think i miss a unsolvable problem on my SwiftUI demo: a simple url image renderer with a sub-render piece, codes here:
import Foundation
import SwiftUI
struct URLImage: View {
var urlString: String;
@State var loaded = false
@State var error: Any?
@State var data: Data?
func didMount() {
print("!!! viewWillAppear", self.urlString)
// just load url and get data in the callback fn:
// (String, (Any?, Data) -> Void) -> Void
// $0 is error, $1 is data
loadImage(urlString: self.urlString) {
print("loaded", $0 ?? "no error", $1)
self.error = $0
self.data = $1
self.loaded = true
}
}
// what is the return-type of tryRender ?
func tryRender() -> View { // doesn't works now because `View` is a protocol
// self.data maybe nil or with a wrong binary format
guard let image = try? Image(nsImage: NSImage(data: self.data!)!) else {
// return Image("image_format_error") // it works with "func tryRender() -> Image" but ... emmm
return Text("image_format_error") // this is what i want, but this can't works
}
return image
}
var body: some View {
self.didMount()
return VStack {
if (self.error != nil) {
Text("URLImage Error")
} else {
if (self.loaded) {
self.tryRender()
} else {
Text("not loaded")
}
}
}
}
}
struct URLImage_Previews: PreviewProvider {
static var previews: some View {
URLImage(
urlString: "http://127.0.0.1:3000/0009.jpg"
)
}
}
the problem is the return type of tryRender(), i can't write tryRender() -> Image | Text
like typescript's union types to express my opinion.
is Image or Text have a base type to make it works ? or there is another way to write such the sub-render pieces func ?
CodePudding user response:
You can use @ViewBuilder
and your return type should be some View
@ViewBuilder func tryRender() -> some View {
if let image = try? Image(nsImage: NSImage(data: self.data!)!) {
image
} else {
Text("image_format_error")
}
}