SwiftUI模态窗口内嵌图片选择弹窗触发CollectionView越界崩溃求助
问题修复:模态窗口打开时崩溃的解决方法
崩溃原因
报错Attempted to scroll the collection view to an out-of-bounds item (0) when there are only 0 items in section 0的核心原因是:当pickedImages为空数组时,设置了.page样式的TabView没有任何可展示内容,但TabView内部的CollectionView仍会尝试滚动到索引0的位置,触发越界崩溃。即便设置了indexDisplayMode: .never,也无法规避这个底层初始化逻辑问题。
解决方案
给空状态的TabView添加一个占位视图,确保TabView始终有至少一个可渲染的内容项,避免空CollectionView触发越界错误。
修改后的代码片段
var body: some View { NavigationView { Form { Section(header: Text("New Item")) { TextField("Title", text: $viewModel.singleitem.title) TextField("Description", text: $viewModel.singleitem.description) } Section(header: Text("Author")) { TextField("Author", text: $viewModel.singleitem.author) } if mode == .edit { Section { Button("Delete item") { self.presentActionSheet.toggle() } .foregroundColor(.red) } } Section(footer: // TABVIEW WITH POPUP WINDOW STARTS HERE TabView { // 添加空状态占位视图 if pickedImages.isEmpty { VStack(spacing: 16) { Image(systemName: "photo.badge.plus") .font(.system(size: 48)) .foregroundColor(.gray) Text("点击右上角按钮添加图片") .font(.subheadline) .foregroundColor(.secondary) } .frame(height: 450) } else { ForEach(pickedImages, id: \.self) { image in GeometryReader { proxy in let size = proxy.size Image(uiImage: image) .resizable() .aspectRatio(contentMode: .fill) .frame(width: size.width, height: size.height) .cornerRadius(15) } .padding() } } } .frame(height: 450) .tabViewStyle(.page(indexDisplayMode: pickedImages.isEmpty ? .never : .always)) .toolbar { Button { showPicker.toggle() } label: { Image(systemName: "plus") } } .popupImagePicker(show: $showPicker) { asset in let manager = PHCachingImageManager.default() let options = PHImageRequestOptions() options.isSynchronous = true DispatchQueue.global(qos: .userInitiated).async { asset.forEach { asset in manager.requestImage(for: asset, targetSize: .init(), contentMode: .default, options: options) { image, _ in guard let image = image else { return } DispatchQueue.main.async { self.pickedImages.append(image) } } } } } ) { EmptyView() } } } }
额外优化建议
- 将空状态占位视图封装成独立
View组件,提升代码可读性 - 确保
pickedImages是@State或@Binding修饰的可观察数组,保证视图能正确响应数据变化
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

