image - SwiftUI、CloudKit 和图像

标签 image swiftui foreach cloudkit ckasset

我真的被一些我认为应该相对容易的事情难住了,所以我需要在正确的方向上有一点小小的突破。我搜索了很多地方,但得到的要么是错误的信息,要么是过时的信息(很多!)。

我正在使用 Core Data 和 CloudKit 在用户设备之间同步数据。我将图像另存为附加到 CKRecord 的 CKAsset。效果很好。问题在于检索图像。我需要列表中每个独特实体(游戏)的图像。因此,我在 viewModel 上编写了一个方法,用于使用 CKAsset 检索记录。这有效(已验证),但我不知道如何获取图像并将其分配给 SwiftUI Image() View 。我当前的方法返回一个带有 UIImage 的闭包,如何将该图像设置为 foreach 中的 Image() 。或者任何其他解决方案表示赞赏。获取图像应该不难吧?

/// Returns the saved UIImage from CloudKit for the game or the default Image!
func getGameImageFromCloud(for game: Game, completion: @escaping (UIImage) -> Void ) {
    // Every game should always have an id (uuid)!
    if let imageURL = game.iconImageURL {
        let recordID = CKRecord.ID(recordName: imageURL)
        var assetURL = ""

        CKContainer.default().privateCloudDatabase.fetch(withRecordID: recordID) { record, error in
            if let error = error {
                print(error.getCloudKitError())
                return
            } else {
                if let record = record {
                    if let asset = record["iconimage"] as? CKAsset {
                        assetURL = asset.fileURL?.path ?? ""
                        DispatchQueue.main.async {
                            completion(UIImage(contentsOfFile: assetURL) ?? AppImages.gameDefaultImage)
                        }
                    }
                }
            }
        }
    } else {
        completion(AppImages.gameDefaultImage)
    }
}

这是我想显示每个游戏的图像的 ForEach(但这在多个地方都需要:

        //Background Tab View
        TabView(selection: $gamesViewModel.currentIndex) {
            ForEach(gamesViewModel.games.indices, id: \.self) { index in
                GeometryReader { proxy in
                    Image(uiImage: gamesViewModel.getGameImageFromCloud(for: gamesViewModel.games[index], completion: { image in
                         
                    }))
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: proxy.size.width, height: proxy.size.height)
                        .cornerRadius(1)
                }
                .ignoresSafeArea()
                .offset(y: -100)
            }
            .onAppear(perform: loadImage)
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        .animation(.easeInOut, value: gamesViewModel.currentIndex)
        .overlay(
            LinearGradient(colors: [
                Color.clear,
                Color.black.opacity(0.2),
                Color.white.opacity(0.4),
                Color.white,
                Color.systemPurple,
                Color.systemPurple
            ], startPoint: .top, endPoint: .bottom)
        )
        .ignoresSafeArea()

TIA!

最佳答案

所以,让我们开始...将 ForEach 图像相关内部结构提取到 subview 中,例如(当然它不可测试,只是想法):

ForEach(gamesViewModel.games.indices, id: \.self) { index in
    GeometryReader { proxy in
        GameImageView(model: gamesViewModel, index: index)     // << here !!
            .frame(width: proxy.size.width, height: proxy.size.height)
            .cornerRadius(1)
            //.onDisappear { // if you think about cancelling
            //   gamesViewModel.cancelLoad(for: index)
            //}
    }
    .ignoresSafeArea()
    .offset(y: -100)
}
.onAppear(perform: loadImage)

现在是 subview 本身

struct GameImageView: View {
  var model: Your_model_type_here
  var index: Int

  @State private var image: UIImage?    // << here !!

  var body: some View {
    Group {
      if let loadedImage = image {
        Image(uiImage: loadedImage)          // << here !!
          .resizable()
          .aspectRatio(contentMode: .fill)
      } else {
        Text("Loading...")
      }
    }.onAppear {
       model.getGameImageFromCloud(for: model.games[index]) { image in
         self.image = image
       }
    }
  }
}

关于image - SwiftUI、CloudKit 和图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73260123/

相关文章:

java - 如何随着窗口大小的调整而调整 JLabel 中图像的大小?如何保持适当的规模?

c# - 如何在不影响宽高比的情况下调整图像大小

swift - 在 SwiftUI 中递归构建菜单

php - for vs foreach vs while 在 php 中遍历数组哪个更快

c# - 如何将 foreach 与二维对象数组一起使用?

flash - 从图库中批量导出图像?

android - 任何用于在 Eclipse 上的 Android 中裁剪图像的好库

swift - Swift Combine PassThroughSubject 发出的意外事件

ios - SwiftUI - 在 `ForEach` 的每个元素之间自动添加分隔符

asynchronous - 在 foreach 循环中,等待不起作用