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

使用按钮切换PageViewController时最后一页崩溃求助

解决PageViewController切换到最后一页时崩溃的问题

从你提供的代码和错误信息来看,崩溃的核心原因是调用setViewControllers时传入了空的视图控制器数组,错误提示里的The number of view controllers provided (0) doesn't match the number required (1)已经明确说明了这点。

问题出在哪里?

看你的nextBtnClicked方法逻辑:

  1. 每次点击先执行currentIndex += 1
  2. 然后判断如果currentIndex == pg.count - 1,就只打日志不处理页面切换
  3. 如果不是最后一页,才尝试获取对应页面并切换

这里有两个致命问题:

  • 当currentIndex已经是最后一页索引(比如pg.count-1)时,点击Next按钮会先把currentIndex变成pg.count,这时候进入else分支调用viewControllerAtIndex(index: currentIndex),而这个索引已经超出了pg的范围,导致返回nil
  • 用[startingViewController] as? [UIViewController]转换时,因为数组里是nil,转换后会变成空数组,传给setViewControllers就触发了崩溃

修复方案

我们需要调整逻辑顺序,先判断是否已经到达最后一页,再执行索引自增和页面切换,同时增加安全校验确保获取到有效的视图控制器:

修改后的nextBtnClicked方法

@objc func nextBtnClicked() {
    guard currentIndex != NSNotFound else { return }
    
    // 先判断是否已经是最后一页
    if currentIndex == pg.count - 1 {
        // 执行跳转到PageViewController外部的逻辑
        log("lastt")
        return
    }
    
    // 还没到最后一页,才自增索引并切换页面
    currentIndex += 1
    
    // 确保能获取到有效的视图控制器
    guard let startingViewController = viewControllerAtIndex(index: currentIndex) else {
        log("Failed to load view controller for index: \(currentIndex)")
        return
    }
    
    pageController?.setViewControllers([startingViewController], direction: .forward, animated: false)
    
    // 同时显示返回按钮(如果之前隐藏了)
    if currentIndex > 0 {
        backBtn.isHidden = false
    }
}

优化后的backBtnClicked方法(增加安全校验)

func backBtnClicked() {
    guard currentIndex > 0 else { return }
    
    currentIndex -= 1
    
    // 控制返回按钮的显示状态
    backBtn.isHidden = currentIndex == 0
    nextBtn.setTitle("Next", for: .normal)
    
    // 确保能获取到有效的视图控制器
    guard let startingViewController = viewControllerAtIndex(index: currentIndex) else {
        log("Failed to load view controller for index: \(currentIndex)")
        return
    }
    
    pageController?.setViewControllers([startingViewController], direction: .reverse, animated: false)
}

额外注意:检查viewControllerAtIndex方法

确保这个方法在索引合法时能返回非空的TableVC,比如加上索引范围校验:

func viewControllerAtIndex(index: Int) -> TableVC? {
    // 先校验索引是否在合法范围内
    guard index >= 0, index < pg.count else {
        log("Invalid index: \(index)")
        return nil
    }
    
    // 这里替换成你实际创建/获取TableVC的逻辑
    let tableVC = TableVC()
    // 配置页面数据,比如 tableVC.data = pg[index]
    return tableVC
}

为什么这样修复?

  1. 逻辑顺序调整:先判断是否到达最后一页,避免索引超出范围
  2. 安全校验:用guard确保获取到有效的视图控制器,防止传入空数组
  3. 状态同步:在切换页面时同步更新按钮的显示状态,避免逻辑混乱

这样修改后,点击Next到最后一页时会执行跳转外部的逻辑,不会触发页面切换;同时所有页面切换操作都会确保传入合法的视图控制器数组,彻底解决崩溃问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:35:29