当前位置: 首页 > news >正文

iOS 如何自定义第一个显示的视图(含 SceneDelegate 删除指南) - 详解

iOS 如何自定义第一个显示的视图(含 SceneDelegate 删除指南) - 详解

一. 引言

在刚创建一个 iOS 工程时,Xcode 会默认生成一个简单的 ViewController 并把它作为 App 启动后展示的第一个页面。但在真实项目中,我们往往需要:

  • 使用 TabBar 作为首页
  • 使用导航控制器包裹首页
  • 动态选择首页(引导页 / 登录页 / 主页面)
  • 使用自己的 AppDelegate 完成初始化逻辑(路由、主题、依赖注入等)

这篇文章就以 真实项目结构 为例,完整讲一下:

  1. 如何在 AppDelegate 中自定义第一个展示页面
  2. 为什么会出现 SceneDelegate
  3. 如何在包含 SceneDelegate 的项目中设置首页
  4. 如果你不需要 SceneDelegate —— 如何“完全移除”它,让项目更简单

二. 移除原根视图控制器

通常来讲ViewController很难满足项目需求,那么第一件事儿应该就是想办法删除这个原来的根视图控制器。

我们可以在左侧文件中找到Main.storyboard,会发现有一个小箭头指向这个ViewController,我们使用鼠标选中小箭头按删除键,即可移除原来的根视图。

三. AppDelegate

其实在iOS13之前,所有的事情都是在AppDelegate中完成的,AppDelegate的代码如下:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {return true}...
}

这是最简单也最容易理解的结构:AppDelegate是整个App的入口,我们可以在这里自己手动创建window,自定义设置根视图控制。

例如一个实际项目的AppDelegate代码如下:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {setupMain()return true}/// 设置 mainprivate func setupMain() {window = UIWindow(frame: UIScreen.main.bounds)let tabBarController = GZTabBarController()let nav = UINavigationController(rootViewController: tabBarController)nav.setNavigationBarHidden(true, animated: false)window?.rootViewController = navwindow?.makeKeyAndVisible()}
}

这种写法极为常见:

  • 手动创建 UIWindow
  • 手动设置 rootViewController
  • 你可以根据业务决定展示 TabBar / 登录页 / 引导页等任意界面

四. SceneDelegate

iOS 13之后多了一个 SceneDelegate,主要是因为iOS 13发布了多窗口(Multiple Scenes)机制,也就是在 iPad 上可以让一个 App 打开多个窗口。

因此苹果新增了 SceneDelegate,用于管理每一个窗口:

application → 多个 scene → 每个 scene 对应一个 UIWindow

所以新工程里你会看到:

  • AppDelegate 不再负责 window
  • SceneDelegate 接管 window 与 rootViewController

4.1 如果你的项目包含 SceneDelegate:那该怎么自定义首页?

就目前来我们能用xcode版本创建的项目必然包含SceneDelegate,但是也不需要慌,只需要把 AppDelegate 的 setupMain() 移到 SceneDelegate:

func scene(_ scene: UIScene,willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) {guard let windowScene = (scene as? UIWindowScene) else { return }window = UIWindow(windowScene: windowScene)let tabBar = GZTabBarController()let nav = UINavigationController(rootViewController: tabBar)nav.setNavigationBarHidden(true, animated: false)window?.rootViewController = navwindow?.makeKeyAndVisible()
}

但是 如果你的项目需要再iOS 13以下的系统中运行,那么AppDelegate中的代码也不能省略。

4.2 但是很多 iPhone App 根本不需要 SceneDelegate —— 可以删除吗?可以!

绝大部分 iPhone 应用并不会用到 iPad 的多窗口,所以 SceneDelegate 完全是累赘。如果你希望项目保持最简单的 AppDelegate + Window 模式,只需要:

删除 SceneDelegate.swift 文件

直接从项目中删掉。

删除 Info.plist 里的 Scene 配置

Application Scene Manifest → UIApplicationSceneManifest

删掉后 App 就不会再尝试创建 Scene 了。

让 AppDelegate 恢复为 window 模式

然后就是把AppDelegate 还当做APP入口,在 didFinishLaunchingWithOptions 中设置 rootViewController。

此时项目就回到最简单、最稳定的结构:AppDelegate 100% 负责。

五. 结语

无论使用哪种结构,都记住一句话:

第一个界面 = window.rootViewController,window 的创建者是谁 → 首页入口就写在哪里。

项目结构

首页入口位置

不含 SceneDelegate

AppDelegate 的 didFinishLaunchingWithOptions

含 SceneDelegate

SceneDelegate 的 scene(_:willConnectTo:)

删除 SceneDelegate

又回到 AppDelegate

在真实项目中,我们一般会:

  • 使用 UINavigationController 包裹 TabBar
  • 隐藏导航栏,由业务统一管理导航样式
  • 为后续引导页 / 登录页 / 路由切换留出空间

这也是大量上线应用的通用写法。

http://www.gsyq.cn/news/120625.html

相关文章:

  • 4、编码过程中的调试技巧
  • GitStats统计工具:全方位Git仓库分析实践指南
  • 零信任架构下的权限革命:MCP PL-600 Agent四级权限落地指南
  • 你真的会用Azure Monitor吗?,AZ-500云Agent集成配置全揭秘
  • 手把手教你构建安全合规的MCP PL-600 Agent权限体系,错过等于隐患
  • Delphi逆向工程完整解决方案:高效恢复源代码的专业指南
  • 别再烧钱了!Azure量子计算成本优化的7个关键检查点
  • 深圳海关律师推荐:专业法律服务选择参考 - 品牌排行榜
  • DP-420图Agent查询慢?5个生产环境验证的优化策略必须掌握
  • 从入门到精通:MCP DP-420图Agent备份技术深度拆解(仅限专业人士参考)
  • 为什么MCP SC-400成为量子加密首选平台?(独家技术内幕曝光)
  • 保姆级解析!Attention Weights 和 Attention是啥?到底怎么算?
  • React Flow v12 自定义节点连接边失效:5步诊断与修复指南
  • 长和宋实探:四大国企联袂,浏阳河畔的宋式美学藏品 - 资讯焦点
  • 2025年铠装缝,变形缝,金刚砂厂家推荐,解读地坪防护与耐磨性能双重适配方案 - 品牌鉴赏师
  • 深度剖析PW6006:快充充电器电压诱骗芯片,助力设备高效取电
  • Chrome垂直标签页:重新定义浏览器标签管理新标准
  • 2025年选择正规精密压延机厂家推荐,有生产资质的精密压延机 - myqiye
  • MCP DP-420图Agent备份实战手册(专家私藏方案曝光)
  • 嘉兴市自建房设计公司评测排行榜:6 家主流企业实地测评,哪家更靠谱? - 苏木2025
  • Mac百度网盘加速工具:解锁高速下载权限终极指南
  • 零样本目标检测实战指南:用语言指令解锁图像理解新维度
  • 【读书笔记】《论扯淡》
  • AI赋能靶向蛋白降解:革新药物发现的新引擎
  • Apollo Save Tool:重新定义游戏存档管理的终极解决方案
  • 【程序源代码】大学校园二手书籍交易小程序(含前后端源码)
  • 业务逻辑多变?XinServer 的表结构好改吗?
  • 【含文档+PPT+源码】基于SpringBoot的校园反电信诈骗宣传系统的设计与实现
  • vue+springboot社区外来务工人员管理系统_数据分析可视化大屏系统10vz9c0a_jz119
  • 41、使用查询表达式的LINQ