SwiftUI - Unwrap optional image data to create Image based on UIImage(data)
You have a few options available. I think the most straightforward is to make an extension on Image and define a new initialiser that will serve your needs:
extension Image {
public init?(data: Data?) {
guard let data = data,
let uiImage = UIImage(data: data) else {
return nil
}
self = Image(uiImage: uiImage)
}
}
Then you can simply use it like this:
Image(data: userService.user.imageData)
since it is nullable
it needs to be contained in another View
with at least one other View
.
If you want to provide a placeholder in place of a missing image you could use an extension like this:
extension Image {
public init(data: Data?, placeholder: String) {
guard let data = data,
let uiImage = UIImage(data: data) else {
self = Image(placeholder)
return
}
self = Image(uiImage: uiImage)
}
}
Then you can simply use it like this:
Image(data: userService.user.imageData, placeholder: "nameOfPlaceholder")
since it is not nullable
it doe not need to be contained in another View
with at least one other View
.
How to unwrap an optional list of type Images in SwiftUI
The simplest direct answer to this is to use the same ??
operator you mentioned to provide an empty array:
struct ContentView : View {
@State var list_of_images : [Image]? = nil
var body: some View {
ForEach(0..<(list_of_images ?? []).count) {
list_of_images?[$0]
.resizable()
.aspectRatio(contentMode: .fill)
}
}
}
However, I'd be concerned in general about the idea of storing the Image
s themselves. I might look into another way of storing references to them (paths? names? UIImages?) that could be iterated over instead. In that case, you could do something like this:
struct ContentView : View {
@State var imageNames : [String]? = nil
var body: some View {
ForEach(imageNames ?? [], id: \.self) { imageName in
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fill)
}
}
}
This approach doesn't work with the array of Image
s because Image
doesn't conform to Identifiable
Update, based on comments:
struct ContentView : View {
@State var images : [UIImage]? = nil
var body: some View {
ForEach(images ?? [], id: \.self) { image in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
}
}
}
How to use published optional properties correctly for SwiftUI
Below is an extension of Binding
you can use to convert a type like Binding<Int?>
to Binding<Int>?
. In your case, it would be URL
instead of Int
, but this extension is generic so will work with any Binding
:
extension Binding {
func optionalBinding<T>() -> Binding<T>? where T? == Value {
if let wrappedValue = wrappedValue {
return Binding<T>(
get: { wrappedValue },
set: { self.wrappedValue = $0 }
)
} else {
return nil
}
}
}
With example view:
struct ContentView: View {
@StateObject private var model = MyModel()
var body: some View {
VStack(spacing: 30) {
Button("Toggle if nil") {
if model.counter == nil {
model.counter = 0
} else {
model.counter = nil
}
}
if let binding = $model.counter.optionalBinding() {
Stepper(String(binding.wrappedValue), value: binding)
} else {
Text("Counter is nil")
}
}
}
}
class MyModel: ObservableObject {
@Published var counter: Int?
}
Result:
How to unwrap an Optional Binding and pass value to another view?
You don't need boundModel
for such body, use instead
var body: some View {
if selectedModel == nil {
Text("Kindly select a value in the list to start editing.")
} else {
EditModelView(model: Binding(selectedModel)!) // << here !!
}
}
Related Topics
Set Uitextfield Placeholder Color Programmatically
Is There an Kotlin Equivalent 'With' Function in Swift
Showing Notification Banner on MAC with Swift
Command Failed Due to Signal: Segmentation Fault: 11 While Emitting Ir Sil Function
Differences Between Filtering Realm with Nspredicate and Block
Swiftui Share Sheet Crashes iPad
Closure:Use Unresolved Identifier 'Self'
How to Get Part of a String in Swift
Swift 3: Converting Data to String Returns a Nil Value
How to Skip Iterations of a For-In Loop (Swift 3)
Swift - Exit Outer Function from Closure
Write into Settings Bundle in Swift
Swift 3 Closure Overload Resolution
How to Implement a Generic Struct That Manages Key-Value Pairs for Userdefaults in Swift