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

iOS应用首次启动引导页设置问题排查及优化方案咨询

问题排查与优化方案

我想给App设置首次下载/重新下载时的引导页,需求是:首次启动显示instructionIntro页面,其余启动场景显示Main页面。目前这段代码写在GuideBookIntroClass里,但现在启动后还是会显示Main.storyboard里的旧引导页,求帮忙排查问题或给更优方案。

当前代码

let isFirstLaunch = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool

if isFirstLaunch == true {
    // 首次启动
    let storyBoard : UIStoryboard = UIStoryboard(name: "instructionIntro", bundle:nil)
    let mainViewController = storyBoard.instantiateViewController(withIdentifier: "instructionIntro") as! InstructionIntroViewController
    let navigationController = UINavigationController(rootViewController: mainViewController)
    if let window = UIApplication.shared.delegate?.window {
          window?.rootViewController = navigationController
    }
}
else {
    // 非首次启动
    let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
    let mainViewController = storyBoard.instantiateViewController(withIdentifier: "Main") as! GuideBookIntroClass
    let navigationController = UINavigationController(rootViewController: mainViewController)
    if let window = UIApplication.shared.delegate?.window {
          window?.rootViewController = navigationController
    }
}

问题排查点

  1. UserDefaults判断逻辑错误:首次启动时isFirstLaunch是nil,nil == true结果为false,会直接走到else分支加载Main页面,完全搞反了首次启动的逻辑。
  2. 代码执行时机太晚:这段代码写在GuideBookIntroClass里,说明App启动时已经先加载了Main.storyboard的页面,再执行这段切换代码,会导致先显示旧引导页再切换(甚至可能因为生命周期问题切换失败)。
  3. 未设置首次启动标记:即使逻辑正确,首次启动后没有把isFirstLaunch设为true,下次启动还是会判定为首次启动。
  4. 控制器类型匹配问题:确认Main.storyboard里标识符为Main的控制器,其类确实是GuideBookIntroClass,避免类型转换崩溃或错误。

优化解决方案

1. 修正UserDefaults逻辑并添加标记设置

把首次启动的判断改成检查isFirstLaunch是否为false,首次启动后立即设置标记:

// 首次启动判断:默认未标记则视为首次启动
let isFirstLaunch = UserDefaults.standard.bool(forKey: "isFirstLaunch")
if !isFirstLaunch {
    // 首次启动:显示引导页
    let storyboard = UIStoryboard(name: "instructionIntro", bundle: nil)
    let introVC = storyboard.instantiateViewController(withIdentifier: "instructionIntro") as! InstructionIntroViewController
    let navVC = UINavigationController(rootViewController: introVC)
    
    // 设置根控制器
    if let window = UIApplication.shared.delegate?.window {
        window?.rootViewController = navVC
    }
    // 标记为已启动过
    UserDefaults.standard.set(true, forKey: "isFirstLaunch")
    UserDefaults.standard.synchronize()
} else {
    // 非首次启动:显示主页面
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let mainVC = storyboard.instantiateViewController(withIdentifier: "Main") as! GuideBookIntroClass
    let navVC = UINavigationController(rootViewController: mainVC)
    
    if let window = UIApplication.shared.delegate?.window {
        window?.rootViewController = navVC
    }
}

2. 调整代码执行位置

把这段代码移到AppDelegate的application(_:didFinishLaunchingWithOptions:)方法里(iOS12及以下),或者SceneDelegate的scene(_:willConnectTo:options:)方法里(iOS13+),确保App启动初期就决定根控制器,避免先加载旧页面。

3. 额外检查项

  • 确认instructionIntro.storyboard的文件名和控制器标识符instructionIntro完全一致,控制器类是InstructionIntroViewController。
  • 确认Main.storyboard里的主控制器标识符为Main,类是GuideBookIntroClass。
  • 如果用的是iOS13+的SceneDelegate,注意获取window的方式是从scene里获取:
// SceneDelegate里获取window的方式
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = navVC
self.window = window
window.makeKeyAndVisible()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:54:18