Как я могу асинхронно загрузить UIImage в изображение SwiftUI?IOS

Программируем под IOS
Ответить
Anonymous
 Как я могу асинхронно загрузить UIImage в изображение SwiftUI?

Сообщение Anonymous »

В SwiftUI есть несколько методов .init для создания изображения, но ни один из них не допускает блокировку или какой-либо другой способ загрузки UIImage из сети/кэша...
Я использую Kingfisher для загрузки изображений из сети и кэширования внутри строки списка, но способ отобразить изображение в представлении — это повторно отобразить его, чего я бы предпочел не делать. Кроме того, я создаю поддельное изображение (только цветное) в качестве заполнителя, пока изображение извлекается.
Другой способ — обернуть все внутри пользовательского представления и повторно отображать только оболочку. Но я еще не пробовал.

Этот образец работает прямо сейчас.
Любая идея по улучшению текущего будет отличной

Некоторые виды с использованием загрузчика

struct SampleView : View {

@ObjectBinding let imageLoader: ImageLoader

init(imageLoader: ImageLoader) {
self.imageLoader = imageLoader
}

var body: some View {
Image(uiImage: imageLoader.image(for: "https://url-for-image"))
.frame(width: 128, height: 128)
.aspectRatio(contentMode: ContentMode.fit)
}

}


import UIKit.UIImage
import SwiftUI
import Combine
import class Kingfisher.ImageDownloader
import struct Kingfisher.DownloadTask
import class Kingfisher.ImageCache
import class Kingfisher.KingfisherManager

class ImageLoader: BindableObject {

var didChange = PassthroughSubject()
private let downloader: ImageDownloader
private let cache: ImageCache
private var image: UIImage? {
didSet {
dispatchqueue.async { [weak self] in
guard let self = self else { return }
self.didChange.send(self)
}
}
}
private var task: DownloadTask?
private let dispatchqueue: DispatchQueue

init(downloader: ImageDownloader = KingfisherManager.shared.downloader,
cache: ImageCache = KingfisherManager.shared.cache,
dispatchqueue: DispatchQueue = DispatchQueue.main) {
self.downloader = downloader
self.cache = cache
self.dispatchqueue = dispatchqueue
}

deinit {
task?.cancel()
}

func image(for url: URL?) -> UIImage {
guard let targetUrl = url else {
return UIImage.from(color: .gray)
}
guard let image = image else {
load(url: targetUrl)
return UIImage.from(color: .gray)
}
return image
}

private func load(url: URL) {
let key = url.absoluteString
if cache.isCached(forKey: key) {
cache.retrieveImage(forKey: key) { [weak self] (result) in
guard let self = self else { return }
switch result {
case .success(let value):
self.image = value.image
case .failure(let error):
print(error.localizedDescription)
}
}
} else {
downloader.downloadImage(with: url, options: nil, progressBlock: nil) { [weak self] (result) in
guard let self = self else { return }
switch result {
case .success(let value):
self.cache.storeToDisk(value.originalData, forKey: url.absoluteString)
self.image = value.image
case .failure(let error):
print(error.localizedDescription)
}
}
}
}

}


Подробнее здесь: https://stackoverflow.com/questions/565 ... chronously
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»