ios - 如何在列表中显示图像 - SwiftUI

标签 ios swift swiftui

我想在我的列表中显示从 json 中检索到的 url 中的图像。我会怎么做?

我尝试只调用图像并输入 url,但它只显示图像的空间,而不是实际图像。

    var body: some View {
        NavigationView {
            List {
                TextField("Search for Meme by name", text: self.$searchItem)


            ForEach(viewModel.memes) { meme in
                HStack {
                    VStack(alignment: .leading, spacing: 2) {
                        Text(meme.name).font(.headline).lineLimit(nil)
                        Image(meme.url).resizable().frame(width: 100, height: 100)

                        }
                    }
                }
            }
        .navigationBarTitle("All Memes")
        }.onAppear {
            self.viewModel.fetchAllMemes()

        }
    }

最佳答案

制作您自己的 View ,该 View 具有自己的 ObservableObject,可下载(并可选地缓存)图像。这是一个例子:

import SwiftUI
import Combine
import UIKit

class ImageCache {
  enum Error: Swift.Error {
    case dataConversionFailed
    case sessionError(Swift.Error)
  }
  static let shared = ImageCache()
  private let cache = NSCache<NSURL, UIImage>()
  private init() { }
  static func image(for url: URL) -> AnyPublisher<UIImage?, ImageCache.Error> {
    guard let image = shared.cache.object(forKey: url as NSURL) else {
      return URLSession
        .shared
        .dataTaskPublisher(for: url)
        .tryMap { (tuple) -> UIImage in
          let (data, _) = tuple
          guard let image = UIImage(data: data) else {
            throw Error.dataConversionFailed
          }
          shared.cache.setObject(image, forKey: url as NSURL)
          return image
        }
        .mapError({ error in Error.sessionError(error) })
        .eraseToAnyPublisher()
    }
    return Just(image)
      .mapError({ _ in fatalError() })
      .eraseToAnyPublisher()
  }
}

class ImageModel: ObservableObject {
  @Published var image: UIImage? = nil
  var cacheSubscription: AnyCancellable?
  init(url: URL) {
    cacheSubscription = ImageCache
      .image(for: url)
      .replaceError(with: nil)
      .receive(on: RunLoop.main, options: .none)
      .assign(to: \.image, on: self)
  }
}

struct RemoteImage : View {
  @ObservedObject var imageModel: ImageModel
  init(url: URL) {
    imageModel = ImageModel(url: url)
  }
  var body: some View {
    imageModel
      .image
      .map { Image(uiImage:$0).resizable() }
      ?? Image(systemName: "questionmark").resizable()
  }
}

关于ios - 如何在列表中显示图像 - SwiftUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58563116/

相关文章:

ios - 尝试创建类似 "test%40test.nl"的字符串时出现 EXC_BAD_ACCES 错误

ios - 在 2 个固定点之间滑动 UIView

ios - 从 CLPlacemark 项中提取 dependentLocality

ios - 在 SwiftUI 中向按钮添加文本和图像

SwiftUI:如何正确地以模态方式呈现 AVPlayerViewController?

ios - 向用户显示替代付款方式。

ios - 是否有一些可以手动显示键盘的ios API

ios - 从应用程序委托(delegate)字符串变量调用电话号码方法时遇到问题

ios - 如何打破导航 Controller 链

appdelegate - 如何使用@EnvironmentObject 在 SwiftUI 中的 AppDelegate 和 SceneDelegate/Views 之间共享数据