You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

分页网格选中图片在预览页无法正常显示及崩溃问题求助

问题分析与解决方案

崩溃直接原因

  1. ViewModel数据不共享:预览页新建了独立的GalleryViewModel实例,和列表页的ViewModel完全隔离——列表页已经加载了第二页图片,但预览页的ViewModel初始为空,调用getPhotosAlbumDetails时用resetPage: false,此时预览页ViewModel的page默认是1,第一次请求只会加载第一页50张图片,而你选中的索引是53,超出了预览页当前加载的图片数量。
  2. 数组越界访问:预览页的photosArray参数默认是空数组,列表页导航时没有传入已加载的图片数组,当代码执行到photosArray[selectedImageIndex]时,直接触发数组越界崩溃。

解决方案

方案一:共享ViewModel(推荐)

让预览页复用列表页的ViewModel,直接使用已加载好的图片数据,无需重复请求:

  1. 修改预览页参数:
struct GalleryPrevIewView: View {
    @State var selectedImageIndex: Int
    @ObservedObject var viewModel: GalleryViewModel // 改为接收外部ViewModel
    var selectedDataID: String = ""

    // 移除原有的 @StateObject private var viewModel = GalleryViewModel()

    var body: some View {
        ZStack {
            Color.black
            TabView(selection: $selectedImageIndex) {
                ForEach(0..<viewModel.photos.count, id: \.self) { index in
                    ZStack(alignment: .topLeading) {
                        URLImageView(url: viewModel.photos[index].photoPath ?? "N/A" , placeholder: "PhotogalleryPlaceholder")
                            .clipped()
                            .scaledToFit()
                            .tag(index)
                            .frame(width: screenWidth)
                    }
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
        .onAppear {
            // 检查选中索引是否超出已加载数量,自动加载后续分页直到覆盖该索引
            while selectedImageIndex >= viewModel.photos.count && viewModel.photos.count < (viewModel.photoDetails?.totalPhotos ?? 0) {
                viewModel.getPhotosAlbumDetails(ID: selectedDataID, resetPage: false) { _ in }
            }
        }
    }
}
  1. 列表页导航时传递ViewModel:
Button {
    selectedImageIndex = ind
    NavigationManager.shared.navigateToRoute(
        .galleryPreview(
            selectedImageIndex: selectedImageIndex ?? 0,
            selectedID: self.selectedDataID,
            viewModel: viewModel // 传递当前ViewModel,需同步修改路由定义
        )
    )
} label: {
    // 原有按钮内容
}

方案二:传递已加载图片数组

如果无法共享ViewModel,就把列表页已加载的图片数组传递给预览页:

  1. 列表页导航传参:
Button {
    selectedImageIndex = ind
    NavigationManager.shared.navigateToRoute(
        .galleryPreview(
            selectedImageIndex: selectedImageIndex ?? 0,
            selectedID: self.selectedDataID,
            photosArray: viewModel.photos // 传入已加载的图片数组
        )
    )
} label: {
    // 原有按钮内容
}
  1. 修改预览页逻辑:
struct GalleryPrevIewView: View {
    @State var selectedImageIndex: Int
    var photosArray: [Photo] // 移除默认空数组,确保必须传入
    @StateObject private var viewModel = GalleryViewModel()
    @State var selectedDataID: String = ""

    var body: some View {
        ZStack {
            Color.black
            TabView(selection: $selectedImageIndex) {
                ForEach(0..<viewModel.photos.count, id: \.self) { index in
                    // 原有图片内容
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
        .onAppear {
            // 同步已加载的图片数组
            viewModel.photos = photosArray
            // 根据每页50张计算当前页码
            viewModel.page = (photosArray.count / 50) + 1
            
            // 检查是否需要加载更多分页覆盖选中索引
            if selectedImageIndex >= viewModel.photos.count && viewModel.photos.count < (viewModel.photoDetails?.totalPhotos ?? 0) {
                viewModel.getPhotosAlbumDetails(ID: selectedDataID, resetPage: false) { status in
                    if status {
                        // 处理极端情况:选中索引超出总图片数,设置为最后一张
                        selectedImageIndex = min(selectedImageIndex, viewModel.photos.count - 1)
                    }
                }
            }
        }
    }
}

紧急修复:避免数组越界

如果暂时无法调整ViewModel或传参逻辑,先给预览页的越界访问加判断:

else if selectedImageIndex < photosArray.count, let matchIndex = viewModel.photos.firstIndex(where: { $0.phID == photosArray[selectedImageIndex].phID }) {
    selectedImageIndex = matchIndex
} else {
    // 索引无效时自动修正为最后一张有效图片
    selectedImageIndex = max(0, viewModel.photos.count - 1)
}

内容的提问来源于stack exchange,提问作者Swift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 01:20:53