SwiftUI Make the content of an Image reactive to a property update

Viewed 142

I have this inside my View:

Image(uiImage: viewModel.emojiImage)

Button(action: {
    viewModel.updatesRandomEmojiImage()
}, label: {
    Text("RANDOM EMOJI")
}).buttonStyle(FilledButton())

and these methods in my ViewModel:

@State var emojiImage: UIImage = UIImage()

func updatesRandomEmojiImage() {
    guard let url = URL(string: randomEmojiUrl()) else { return }
    downloadEmojiImage(fromUrl: url)
}
    
func randomEmojiUrl() -> String {
    repository.emojis().randomElement()?.imageUrl ?? ""
}
    
private func downloadEmojiImage(fromUrl url: URL) {
    if let data = try? Data(contentsOf: url) {
        self.emojiImage = UIImage(data: data)!
    }
}

I'm trying to make that the Image content changes whenever I click on the "RANDOM EMOJI" button. How can I do that?

1 Answers

I found an answer for this problem. What I did was:

In VM I made my image a @Published instead of @State:

@Published var emojiImage: UIImage? = nil

Then, in the View what I did was add the .onReceive call and an image using @State:

@State private var emojiImage: UIImage?

var body: some View {
    ZStack {
        emojiImage.map{Image(uiImage: $0)}             
    }.onReceive(viewModel.$emojiImage) { image 
        self.emojiImage = image
    }
}
Related