如何修改Swift并发代码使图片选择顺序与展示顺序一致?
解决图片选择顺序与展示顺序匹配的问题
当前代码中,选择图片后会为每个图片项创建独立异步任务加载,导致图片按加载完成顺序展示,而非选择时的顺序。要利用Swift Concurrency保证顺序匹配,只需调整加载逻辑,确保按选择顺序依次加载图片。
修改核心代码
1. 调整ViewModel的加载逻辑
将单个图片加载改为返回模型,并新增批量加载函数控制顺序:
@MainActor class ExampleViewViewModel: ObservableObject { @Published var selectedItems: [PhotosPickerItem] = [] @Published var selectedImages: [RectangleProfileImage] = [] // 单个图片加载:返回对应模型,不直接修改数组 private func loadSingleItem(item: PhotosPickerItem) async -> RectangleProfileImage { do { let data = try await item.loadTransferable(type: Data.self) guard let data else { return RectangleProfileImage(image: Image(systemName: "exclamationmark.triangle.fill"), hasfailed: true) } if let uiImage = UIImage(data: data) { let image = Image(uiImage: uiImage) return RectangleProfileImage(image: image) } else { return RectangleProfileImage(image: Image(systemName: "exclamationmark.triangle.fill"), hasfailed: true) } } catch { print("Error loading image: \(error.localizedDescription)") return RectangleProfileImage(image: Image(systemName: "exclamationmark.triangle.fill"), hasfailed: true) } } // 批量加载:按选择顺序依次加载所有图片 func loadAllItems() async { selectedImages.removeAll() for item in selectedItems { let imageModel = await loadSingleItem(item: item) selectedImages.append(imageModel) } } }
2. 修改View的触发逻辑
在onChange中调用批量加载函数,而非循环创建独立Task:
.onChange(of: viewModel.selectedItems) { pickerItems in Task { await viewModel.loadAllItems() } }
改动说明
- 单个加载函数仅负责处理单张图片的转换,将顺序控制交给批量加载逻辑
- 批量加载时按选择顺序逐个await加载任务,确保每张图片加载完成后再处理下一张,保证
selectedImages的顺序与选择顺序完全一致 - 仅创建一个顶层Task,避免多任务并发导致的顺序混乱
内容的提问来源于stack exchange,提问作者byaruhaf
相关产品推荐
相关产品推荐

