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

Swift中TableView嵌套CollectionView滚动至第25项时崩溃问题求助

问题分析与解决方案

崩溃原因

你遇到的崩溃核心原因很明确:UICollectionView的item索引是从0开始计数的——你的CollectionView有25个单元格,所以有效的item索引范围是0到24,但崩溃时你尝试滚动到item:25,这超出了合法范围,系统因此抛出NSInvalidArgumentException异常。

修复崩溃+实现自动滚动到下一个单元格的方案

我们需要同时解决索引越界问题,以及实现操作后自动滚动的逻辑,具体步骤如下:

1. 修正viewWillAppear中的滚动越界问题

先修改你当前的页面显示逻辑,添加索引边界校验,确保滚动的目标始终在合法范围内:

var enabledID = Int() // 建议用小驼峰命名,符合Swift编码规范
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated) // 别忘了调用父类的生命周期方法
    enabledID = UserDefaults.standard.integer(forKey: "EnabledID")
    
    // 强制让enabledID落在合法索引范围内:0 ≤ 值 ≤ 24
    let maxValidIndex = myCollectionView.numberOfItems(inSection: 0) - 1
    enabledID = max(0, min(enabledID, maxValidIndex))
    
    if enabledID == 0 {
        UserDefaults.standard.set(1, forKey: "EnabledID")
    } else {
        let targetIndex = IndexPath(item: enabledID, section: 0)
        myCollectionView.scrollToItem(at: targetIndex, at: .centeredHorizontally, animated: true)
    }
}

2. 实现操作后自动滚动到下一个单元格的逻辑

假设你是在点击CollectionView单元格后触发滚动,你可以在didSelectItemAt代理方法中添加如下逻辑:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let maxValidIndex = collectionView.numberOfItems(inSection: 0) - 1
    let nextItemIndex = indexPath.item + 1
    
    // 处理边界情况:如果已经是最后一个单元格
    guard nextItemIndex <= maxValidIndex else {
        // 这里可以选择两种逻辑:
        // 逻辑1:不滚动,保持在最后一个
        // return
        
        // 逻辑2:循环滚动到第一个单元格(示例用这个)
        let firstIndex = IndexPath(item: 0, section: 0)
        collectionView.scrollToItem(at: firstIndex, at: .centeredHorizontally, animated: true)
        UserDefaults.standard.set(0, forKey: "EnabledID")
        return
    }
    
    // 正常滚动到下一个单元格
    let nextIndex = IndexPath(item: nextItemIndex, section: 0)
    collectionView.scrollToItem(at: nextIndex, at: .centeredHorizontally, animated: true)
    
    // 更新UserDefaults,确保下次进入页面能定位到正确位置
    UserDefaults.standard.set(nextItemIndex, forKey: "EnabledID")
}

额外优化建议

  • 不要硬写单元格数量(比如直接用24),用collectionView.numberOfItems(inSection: 0) - 1动态获取最大合法索引,后续修改CollectionView的单元格数量时,代码不需要同步改动。
  • 变量名EnabledID建议改成lastSelectedCollectionItemIndex,更贴合语义,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:11:20