首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >下载图像后在SwiftUI中更新图像视图

下载图像后在SwiftUI中更新图像视图
EN

Stack Overflow用户
提问于 2019-07-12 14:05:43
回答 1查看 3.8K关注 0票数 1

在点击一个按钮,我试图下载一个新的随机图像和更新视图。当应用程序加载时,它会显示下载的图像。当单击按钮时,图像似乎是下载的,但是视图从未更新过,并显示了place图像。我是不是漏掉了什么,有什么想法吗?这是一个简化的版本。

代码语言:javascript
运行
复制
import SwiftUI

struct ContentView : View {

    @State var url = "https://robohash.org/random.png"

    var body: some View {
        VStack {
            Button(action: {
                self.url = "https://robohash.org/\(Int.random(in:0 ..< 10)).png"
            }) {
                Text("Get Random Robot Image")
            }
            URLImage(url: url)
        }

    }
}
代码语言:javascript
运行
复制
class ImageLoader: BindableObject {

    var downloadedImage: UIImage?
    let didChange = PassthroughSubject<ImageLoader?, Never>()

    func load(url: String) {

        guard let imageUrl = URL(string: url) else {
            fatalError("Image URL is not correct")
        }

        URLSession.shared.dataTask(with: imageUrl) { data, response, error in
            guard let data = data, error == nil else {
                DispatchQueue.main.async {
                    self.didChange.send(nil)
                }
                return
            }

            self.downloadedImage = UIImage(data: data)
            DispatchQueue.main.async {
                print("downloaded image")
                self.didChange.send(self)
            }
        }.resume()
    }
}
代码语言:javascript
运行
复制
import SwiftUI

struct URLImage : View {

    @ObjectBinding private var imageLoader = ImageLoader()
    var placeholder: Image

    init(url: String, placeholder: Image = Image(systemName: "photo")) {
        self.placeholder = placeholder
        self.imageLoader.load(url: url)
    }

    var body: some View {
        if let uiImage = self.imageLoader.downloadedImage {
            print("return downloaded image")
            return Image(uiImage: uiImage)
        } else {
            return placeholder
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-13 19:36:10

这个问题似乎与ContentViewImageURL之间的某种丢失的同步有关(在按钮单击事件之后发生)。

一个可能的解决办法是使ImageURL成为ContentView的一个@State属性。

之后,在按钮单击事件的范围内,我们可以调用image.imageLoader.load(url: )方法。当图像下载结束时,发布者(didChange)将通知ImageURL,然后更改将正确传播到ContentView

代码语言:javascript
运行
复制
import SwiftUI
import Combine

enum ImageURLError: Error {
    case dataIsNotAnImage
}

class ImageLoader: BindableObject {
    /*
    init(url: URL) {
        self.url = url
    }

    private let url: URL */

    let id: String = UUID().uuidString
    var didChange = PassthroughSubject<Void, Never>()

    var image: UIImage? {
        didSet {
            DispatchQueue.main.async {
                self.didChange.send()
            }
        }
    }

    func load(url: URL) {
        print(#function)
        self.image = nil

        URLSession.shared.dataTask(with: url) { (data, res, error) in
            guard error == nil else {
                return
            }

            guard
                let data = data,
                let image = UIImage(data: data)
            else {
                return
            }

            self.image = image
        }.resume()
    }

}

URLImage视图:

代码语言:javascript
运行
复制
struct URLImage : View {

    init() {
        self.placeholder = Image(systemName: "photo")
        self.imageLoader = ImageLoader()
    }

    @ObjectBinding var imageLoader: ImageLoader

    var placeholder: Image

    var body: some View {
        imageLoader.image == nil ?
            placeholder : Image(uiImage: imageLoader.image!)
    }
}

ContentView

代码语言:javascript
运行
复制
struct ContentView : View {

    @State var url: String = "https://robohash.org/random.png"
    @State var image: URLImage = URLImage()

    var body: some View {
        VStack {
            Button(action: {
                self.url = "https://robohash.org/\(Int.random(in: 0 ..< 10)).png"
                self.image.imageLoader.load(url: URL(string: self.url)!)
            }) {
                Text("Get Random Robot Image")
            }

            image
        }
    }
}

无论如何,我会尝试调查这个问题,如果我知道一些新的东西,我会修改我的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57008629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档