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

iOS开发进阶(十一):ViewController 控制器详解

文章目录

    • 一、前言
    • 二、UIViewController
    • 三、UINavigationController
    • 四、UITabBarController
    • 五、UIPageViewController
    • 六、拓展阅读

一、前言

iOS 界面开发最重要的首属ViewControllerViewViewControllerView的控制器,也就是一般的页面,用来管理页面的生命周期(它相当于安卓里的Activity,两者很像,但又有一些差异)。

ViewController的特点是它有好几种。一种最基本的UIViewController,和另外三种容器:UINavigationControllerUITabBarControllerUIPageViewController

所谓容器,就是它们本身不能单独用来显示,必须在里面放一个或几个UIViewController

不同容器有不同的页面管理方式和展示效果:

  • UINavigationController 用于导航栏管理页面;
  • UITabBarController 用于底部tab管理页面;
  • UIPageViewController 用于切换器管理页面;

容器还可以嵌套,比如把UITabBarController放进UINavigationController里面,这样在tab页面里,可以用启动导航栏样式的二级子页面。

二、UIViewController

这是最简单的页面,没有导航栏。

使用present方法展示,展示时从底部弹起,可以用下滑手势关闭,也可以多次启动叠加多个页面。

在这里插入图片描述

代码实现如下:

class ViewController: UIViewController {override func viewDidLoad() {super.viewDidLoad()// Do any additional setup after loading the view.title = "\(self.hash)"var label = UIButton(frame: CGRect(x: 10, y: 100, width: 300, height: 100))label.setTitle("present ViewController", for: .normal)view.addSubview(label)label.addTarget(self, action: #selector(presentVC), for: .touchUpInside)label = UIButton(frame: CGRect(x: 10, y: 200, width: 300, height: 100))label.setTitle("present NavigationController", for: .normal)view.addSubview(label)label.addTarget(self, action: #selector(presentNC), for: .touchUpInside)label = UIButton(frame: CGRect(x: 10, y: 300, width: 300, height: 100))label.setTitle("push ViewController", for: .normal)view.addSubview(label)label.addTarget(self, action: #selector(pushVC), for: .touchUpInside)label = UIButton(frame: CGRect(x: 10, y: 400, width: 300, height: 100))label.setTitle("present TabbarController", for: .normal)view.addSubview(label)label.addTarget(self, action: #selector(presentTC), for: .touchUpInside)label = UIButton(frame: CGRect(x: 10, y: 500, width: 300, height: 100))label.setTitle("present PageViewController", for: .normal)view.addSubview(label)label.addTarget(self, action: #selector(presentPC), for: .touchUpInside)}@objc func presentVC() {let vc = ViewController()vc.view.backgroundColor = .darkGraypresent(vc, animated: true)}@objc func presentNC() {let vc = ViewController()vc.view.backgroundColor = .graylet nc = UINavigationController(rootViewController: vc)present(nc, animated: true)}@objc func presentTC() {let tc = MyTabbarController()tc.view.backgroundColor = .bluelet nc = UINavigationController(rootViewController: tc)present(nc, animated: true)}@objc func presentPC() {let pc = MyPageViewController()pc.view.backgroundColor = .redlet nc = UINavigationController(rootViewController: pc)present(nc, animated: true)}@objc func pushVC() {let vc = ViewController()vc.view.backgroundColor = .purpleif let nc = navigationController {nc.pushViewController(vc, animated: true)} else {print("navigationController nil!")}}
}

三、UINavigationController

这是最常用的页面导航方式,顶部展示导航栏,有标题、返回按钮。

使用pushViewController方法展示,展示时从右往左出现,可以用右滑手势关闭,也可以多次启动叠加多个页面。

注意⚠️:UINavigationController用来管理一组UIViewController,这些UIViewController共用一个导航栏。

一般来说,UINavigationController能很好地控制导航栏上面的元素显示和转场效果。

如果需要定制导航栏元素,尽量修改UIViewController的导航栏,不要直接修改UINavigationController的导航栏。

在这里插入图片描述

四、UITabBarController

这个一般用来做主页面的展示,下面配置多个tab,用于切换页面。

在这里插入图片描述

示例代码如下:

class MyTabbarController: UITabBarController {init() {super.init(nibName: nil, bundle: nil)self.tabBar.backgroundColor = .graylet vc1 = ViewController()vc1.tabBarItem.image = UIImage(named: "diamond")vc1.tabBarItem.title = "tab1"vc1.view.backgroundColor = .redlet vc2 = ViewController()vc2.tabBarItem.image = UIImage(named: "diamond")vc2.tabBarItem.title = "tab2"vc2.view.backgroundColor = .bluelet vc3 = ViewController()vc3.tabBarItem.image = UIImage(named: "diamond")vc3.tabBarItem.title = "tab3"vc3.view.backgroundColor = .purpleself.viewControllers = [vc1,vc2,vc3,]}required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}
}

五、UIPageViewController

这个用来做翻页的页面,比如电子书或者广告banner。可以配置左右或上下翻译,翻页效果可以配置滚动或者模拟翻书。

viewControllerBeforeviewControllerAfter回调方法控制页面切换。viewControllerBefore方法提供当前页面的前一个页面,viewControllerAfter方法提供当前页面的后一个页面。

注意⚠️:UIPageViewController有预加载机制,它会提前加载当前页面的前后页面。但是没有实现页面缓存机制,需要在外部做缓存。

如果页面非常多,但又是同一个类的实例,那么一般创建三个实例就够了,然后在viewControllerBeforeviewControllerAfter方法里循环使用这三个。

在这里插入图片描述 在这里插入图片描述

示例代码如下:

class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource {lazy var vcs = [ViewController(),ViewController(),ViewController(),ViewController(),ViewController(),]init() {super.init(transitionStyle: .scroll, navigationOrientation: .horizontal)self.dataSource = selflet vc1 = ViewController()vc1.view.backgroundColor = .redlet vc2 = ViewController()vc2.view.backgroundColor = .bluelet vc3 = ViewController()vc3.view.backgroundColor = .purplelet vc4 = ViewController()vc4.view.backgroundColor = .grayvcs = [vc1,vc2,vc3,vc4]self.setViewControllers([vcs[0]], direction: .forward, animated: false)}required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {let i = (vcs.firstIndex(of: viewController as! ViewController) ?? 0) - 1if i < 0 {return nil}return vcs[i]}func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {let i = (vcs.firstIndex(of: viewController as! ViewController) ?? 0) + 1if i >= vcs.count {return nil}return vcs[i]}
}

六、拓展阅读

  • 《iOS开发进阶(十):viewController生命周期讲解》

相关文章:

iOS开发进阶(十一):ViewController 控制器详解

文章目录 一、前言二、UIViewController三、UINavigationController四、UITabBarController五、UIPageViewController六、拓展阅读 一、前言 iOS 界面开发最重要的首属ViewController和View&#xff0c;ViewController是View的控制器&#xff0c;也就是一般的页面&#xff0c;…...

修改mysql密码

1.在此处文件夹下打开cmd 2.输入命令mysqladmin -uroot -p旧密码 password 新密码 3.在navicat进行测试连接...

uniapp 使用命令行创建vue3 ts 项目

命令行创建 uni-app 项目&#xff1a; vue3 ts 版 npx degit dcloudio/uni-preset-vue#vite-ts 项目名称注意 Vue3/Vite版要求 node 版本^14.18.0 || >16.0.0 如果下载失败&#xff0c;请去gitee下载 https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts…...

一周学会Django5 Python Web开发-Django5模型定义

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计41条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…...

kingbaseESV8逻辑备份还原

数据库逻辑备份还原 sys_dump -h127.0.0.1 -Usystem -f/home/kingbase/db01.dmp db01 ksql -h127.0.0.1 test system -c drop database db01 ksql -h127.0.0.1 test system -c create database db01 ksql -h127.0.0.1 -Usystem -ddb01 -f/home/kingbase/db01.dmp --------…...

FreeRtos作业1

1.总结keil5下载代码和编译代码需要注意的事项 代码写完之后的操作流程 2.总结STM32Cubemx的使用方法和需要注意的事项 选择芯片型号 生成代码 3.总结STM32Cubemx配置GPIO的方法 4、使用定时器2让黄灯闪烁 /* USER CODE END Header */ /* Includes --------------------------…...

spring boot dynamic 动态数据数据源配置连接池

前言 我们可以使用 dynamic-datasource 来快速实现多数据源&#xff0c;但是多数据源配置连接池 以及说明文档都是收费的。 这里整理的连接池的配置以及配置说明 连接池配置 &#xff08;druid或者 hikari 选择一个即可&#xff09; 特此说明 如果配置配到了 spring.datasour…...

vue3中如何使用 watch 函数来观察响应式数据的变化

前言 在 Vue 3 中&#xff0c;可以使用 watch 函数来观察响应式数据的变化。这个函数可以在组件的 setup 函数中使用。watch()方法还可以实现更多复杂的功能&#xff0c;比如异步获取数据并在数据更新时重新渲染页面。 代码示例 1、以下是一个使用 Vue 3 watch 函数的简单示例…...

自建机房私有云吗?

大家好&#xff0c;我是小码哥&#xff0c;之前一种有没搞清楚公有云、私有云的概念&#xff0c;今天算是弄清楚了&#xff0c;这里给大家分享一下公有云、私有云的区别&#xff0c;以及自建机房算不算私有云&#xff01; 其实私有云&#xff08;Private Cloud&#xff09;和公…...

解决npm init vue@latest证书过期问题:npm ERR! code CERT_HAS_EXPIRED

目录 一. 问题背景 二. 错误信息 三. 解决方案 3.1 临时解决办法 3.2 安全性考量 一. 问题背景 我在试图创建一个新的Vue.js项目时遇到了一个问题&#xff1a;npm init vuelatest命令出现了证书过期的错误。不过这是一个常见的问题&#xff0c;解决起来也简单。 二. 错误…...

缓存和缓存的常用使用场景

想象一下,一家公司在芬兰 Google Cloud 数据中心的服务器上托管一个网站。对于欧洲用户来说,加载可能需要大约 100 毫秒,但对于墨西哥用户来说,加载需要 3-5 秒。幸运的是,有一些策略可以最大限度地减少远程用户的请求延迟。 这些策略称为缓存和内容交付网络 (CDN),它们是…...

模板方法模式(继承的优雅使用)

目录 前言 UML plantuml 类图 实战代码 AbstractRoutingDataSource DynamicDataSource DynamicDataSourceContextHolder 前言 在设计类时&#xff0c;一般优先考虑使用组合来替代继承&#xff0c;能够让程序更加的灵活&#xff0c;但这并不意味着要完全抛弃掉继承。 …...

百度智能云千帆,产业创新新引擎

本文整理自 3 月 21 日百度副总裁谢广军的主题演讲《百度智能云千帆&#xff0c;产业创新新引擎》。 各位领导、来宾、媒体朋友们&#xff0c;大家上午好。很高兴今天在石景山首钢园&#xff0c;和大家一起沟通和探讨大模型的发展趋势&#xff0c;以及百度最近一段时间的思考和…...

Python下载cuda包失败后到成功(方便使用GPU加速运算,显著提高代码运行速度)

一、查询自己电脑上的cuda版本方法&#xff1a; 1.在windows的cmd里查询显卡cuda的版本号,命令行输入&#xff1a;nvidia-smi 2.在NVIDIA控制面板上寻找自己电脑上cuda的版本 二、安装支持的cuda的python cupy库 因为我的电脑上为cuda11.4,所以使用cuda114&#xff0c;不同的版…...

【Flink】Flink 处理函数之基本处理函数(一)

1. 处理函数介绍 流处理API&#xff0c;无论是基本的转换、聚合、还是复杂的窗口操作&#xff0c;都是基于DataStream进行转换的&#xff0c;所以统称为DataStreamAPI&#xff0c;这是Flink编程的核心。 但其实Flink为了更强大的表现力和易用性&#xff0c;Flink本身提供了多…...

【Java - 框架 - Lombok】(2) SpringBoot整合Lombok完成日志的创建使用 - 快速上手;

"SpringBoot"整合"Lombok"完成日志的创建使用 - 快速上手&#xff1b; 环境 “Java"版本"1.8.0_202”&#xff1b;“Lombok"版本"1.18.20”&#xff1b;“Spring Boot"版本"2.5.9”&#xff1b;“Windows 11 专业版_22621…...

linux 系统安装php 8.0.2

1. 安装包准备 https://www.php.net/distributions/php-8.0.22.tar.gz 我下载到 /usr/local/src 这个目录了 cd /usr/local/srcwget https://www.php.net/distributions/php-8.0.22.tar.gz 2. tar 解压 然后进到解压的文件夹 tar -zxvf php-8.0.22.tar.gz cd php-8.0.2…...

你管这破玩意叫网络

你是一台电脑&#xff0c;你的名字叫 A 很久很久之前&#xff0c;你不与任何其他电脑相连接&#xff0c;孤苦伶仃。 直到有一天&#xff0c;你希望与另一台电脑 B 建立通信&#xff0c;于是你们各开了一个网口&#xff0c;用一根网线连接了起来。 用一根网线连接起来怎么就能…...

系统开发实训小组作业week5 —— 用例描述与分析

目录 1、电影管理 1.1、 用例描述 1.2、 活动图 1.3、 界面元素 1.4、 功能 2、用户管理 2.1、 用例描述 2.2、 活动图 2.3、 界面元素 2.4、 功能 1、电影管理 1.1、 用例描述 用例号 UC009-01 用例名称 电影管理 用例描述 管理员实现对电影信息、座位数量、价…...

C语言例4-35:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡、问鸡翁、鸡母和鸡雏各几何?

方法一&#xff1a; 代码如下&#xff1a; //鸡翁一&#xff0c;值钱五&#xff1b;鸡母一&#xff0c;值钱三&#xff1b;鸡雏三&#xff0c;值钱一。百钱买百鸡、问鸡翁、鸡母和鸡雏各几何&#xff1f; //方法一&#xff1a; #include<stdio.h> int main(void) {int x…...

OpenClaw机械爪MuJoCo仿真沙盒:从算法验证到仿真到现实迁移

1. 项目概述&#xff1a;一个为开源机械爪打造的“数字沙盘”如果你对机器人、开源硬件或者DIY自动化项目感兴趣&#xff0c;最近可能听说过“OpenClaw”这个名字。它是一款设计精巧、成本可控的开源机械爪&#xff0c;社区里不少爱好者都在用它来搭建自己的机器人手臂或者自动…...

系统发育树可视化终极指南:用TreeViewer轻松创建专业级进化树

系统发育树可视化终极指南&#xff1a;用TreeViewer轻松创建专业级进化树 【免费下载链接】TreeViewer Cross-platform software to draw phylogenetic trees 项目地址: https://gitcode.com/gh_mirrors/tr/TreeViewer 你是否曾为系统发育树的可视化而烦恼&#xff1f;面…...

HTML5中Canvas文本对齐TextAlign与基线控制

...

JiT源码深度剖析:从Denoiser到Transformer的完整实现

JiT源码深度剖析&#xff1a;从Denoiser到Transformer的完整实现 【免费下载链接】JiT PyTorch implementation of JiT https://arxiv.org/abs/2511.13720 项目地址: https://gitcode.com/gh_mirrors/jit8/JiT JiT&#xff08;Just image Transformer&#xff09;是一个…...

Kafka 场景化面试题top4: 消息积压(Lag)的紧急处理

场景&#xff1a;凌晨 3 点&#xff0c;监控系统报警&#xff0c;发现某个核心 Topic 的消息积压了上千万条&#xff0c;且消费速度远远跟不上生产速度。作为值班工程师&#xff0c;你该如何快速恢复业务&#xff0c;减少积压&#xff1f; 紧急处理四步走&#xff08;SOP&#…...

终极开源解决方案:用Video-subtitle-extractor高效提取视频硬字幕的完整指南

终极开源解决方案&#xff1a;用Video-subtitle-extractor高效提取视频硬字幕的完整指南 【免费下载链接】video-subtitle-extractor 视频硬字幕提取&#xff0c;生成srt文件。无需申请第三方API&#xff0c;本地实现文本识别。基于深度学习的视频字幕提取框架&#xff0c;包含…...

独立开发者如何通过taotoken以更低成本实验多种大模型能力

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 独立开发者如何通过Taotoken以更低成本实验多种大模型能力 对于独立开发者或小型工作室而言&#xff0c;在项目原型阶段验证不同大…...

CMU开源localPlanner避坑指南:从仿真到实车,ROS小车部署的5个关键步骤

CMU开源localPlanner避坑指南&#xff1a;从仿真到实车&#xff0c;ROS小车部署的5个关键步骤 当学术论文中的算法终于有了开源实现&#xff0c;那种跃跃欲试的心情每个机器人开发者都懂。但真正把代码下载到本地&#xff0c;准备部署到自己的ROS小车上时&#xff0c;才发现从理…...

[特殊字符] 论文查重居然能白嫖?这个AI工具的底层逻辑,今天给你讲透

同学们&#xff0c;我是你们的论文写作科普老友。 今天这期不教写作技巧&#xff0c;专门来聊一个所有人写完论文都绕不开、却很少有人真正搞懂的东西——查重。 你肯定遇到过这种场景&#xff1a;论文写了两万字&#xff0c;满怀信心提交查重&#xff0c;结果报告一出来&…...

思源宋体完全指南:7种字体样式免费商用,打造专业中文排版

思源宋体完全指南&#xff1a;7种字体样式免费商用&#xff0c;打造专业中文排版 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为设计项目寻找既专业又免费的中文字体而烦恼吗&a…...