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生命周期讲解》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2906096.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

HCIP【GRE VPN配置】

实验要求&#xff1a; 按照图式配置IP地址在R1和R3上配置默认路由使公网区域互通在R1和R3上配置GRE VPN&#xff0c;使两端私网能够互相访问&#xff0c;Tunnel口的IP地址如图所示在R1和R3上配置RIPv2、OSPF或者静态路由传递两端私网路由 实验图式如下&#xff1a; 实验配置思…

苹果iOS系统ipa签名圈内和圈外的区别是什么

哈喽&#xff0c;大家好&#xff0c;咕噜淼淼又来和见面啦&#xff0c;最近有好多小伙伴都在疑惑苹果iOS系统ipa签名为什么还有圈内圈外之分&#xff0c;在签名市场中&#xff0c;与客户在寻谈价格的时候&#xff0c;总是会问到圈内和圈外价格多少&#xff0c;为什么圈外价格要…

如何使用固定公网地址远程连接Python编译器并将运行结果返回到Pycharm

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

数据库系统概论(超详解!!!) 第四节 关系数据库标准语言SQL(Ⅱ)

1.数据查询 SELECT [ ALL | DISTINCT] <目标列表达式>[&#xff0c;<目标列表达式>] … FROM <表名或视图名>[&#xff0c; <表名或视图名> ] … [ WHERE <条件表达式> ] [ GROUP BY <列名1> [ HAVING <条件表达式> ] ] [ ORDER BY…

Python-VBA编程500例-024(入门级)

字符串写入的行数(Line Count For String Writing)在实际应用中有着广泛的应用场景。常见的应用场景有&#xff1a; 1、文本编辑及处理&#xff1a;在编写或编辑文本文件时&#xff0c;如使用文本编辑器或文本处理器&#xff0c;经常需要处理字符串并确定其在文件中的行数。这…

Aurora IP的Framing帧接口和Streaming流接口

本文介绍Aurora IP配置时要选择的接口类型以及两种接口类型之前的区别。 Aurora IP接口有两种模式&#xff1a;Framing帧接口&#xff0c;Streaming流接口 目前一直在用的都是Framing帧接口。 Framing帧接口和Streaming流接口的主要区别是什么呢&#xff1f; 顾名思义&#x…

微信开发者工具接入短剧播放器插件

接入短剧播放插线 申请添加插件基础接入app.jsonapp.jsplayerManager.js数据加密跳转到播放器页面运行出错示例小程序页面页面使用的方法小程序输入框绑定申请添加插件 添加插件:登录微信开发者平台 ——> 设置 ——> 第三方设置 ——> 插件管理 ——> 搜索“短剧…

【数据结构 | 图论】如何用链式前向星存图(保姆级教程,详细图解+完整代码)

一、概述 链式前向星是一种用于存储图的数据结构&#xff0c;特别适合于存储稀疏图&#xff0c;它可以有效地存储图的边和节点信息&#xff0c;以及边的权重。 它的主要思想是将每个节点的所有出边存储在一起&#xff0c;通过数组的方式连接&#xff08;类似静态数组实现链表…

云存储比起自建服务器做数据存储的好处是什么?

近年来&#xff0c;国内科技行业开始趋于饱和&#xff0c;越来越多的企业将海外业务作为新的增长点。 但由于国内外政策、市场等因素不同&#xff0c;在出海过程中&#xff0c;安全合规、海外业务保障、应对各地区合规挑战成为企业最普遍的需求之一。 最基本的问题之一是&…

餐饮行业在线预约小程序 提前取号小程序源码系统 带完整的安装代码包以及搭建教程

移动互联网的快速发展&#xff0c;餐饮行业也在不断探索与新兴技术的融合。传统的餐厅预约、取号方式已经无法满足消费者日益增长的便捷性需求。下面&#xff0c;小编给大家分享一款专为餐饮行业打造的在线预约小程序源码系统&#xff0c;旨在帮助餐厅实现智能化、高效化的服务…

软件测试基础理论、测试用例及设计方法、易混淆概念总结【软件测试】

一.软件测试基础理论 1.软件定义 软件是计算机系统中与硬件相互依存的一部分&#xff0c;包括程序、数据以及与其相关文档 的完整集合。 程序是按事先设计的功能和性能要求执行的指令序列&#xff1b; 数据是使程序能正常操作信息的数据结构&#xff1b; 文档是与程序开发、维…

【Python函数和类2/6】函数的参数

目录 目标 为函数设置参数 传递实参 关键字实参 关键字实参的顺序 位置实参 常见错误 缺少实参 位置实参的顺序 默认值形参 参数的优先级 默认值形参的位置 总结 目标 上篇博客中&#xff0c;我们在定义函数时&#xff0c;使用了空的括号。这表示它不需要任何信息就…

使用AOP实现打印日志

首先创建annotation.SystemLog类&#xff1a; package com.gjh.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;Target(ElementType.METHOD…

海外短剧系统搭建影视类分销软件APP开发网剧CPS分销系统H5,海外短剧国际版源码系统:连接世界,共享短剧文化。

目录 一、海外短剧系统搭建部署流程 二、开发完善的系统模板功能展示 总结&#xff1a; 一、海外短剧系统搭建部署流程 搭建和部署海外短剧系统需要经过以下步骤&#xff1a; 系统设计&#xff1a;首先需要进行系统设计&#xff0c;确定系统的功能和需求。包括用户注册登录、…

区块链dapp开发 dapp系统开发方案

在区块链技术的兴起和普及的推动下&#xff0c;去中心化应用程序&#xff08;DApp&#xff09;成为了当前数字世界中的热门话题之一。DApp 的开发不仅需要考虑技术方面的挑战&#xff0c;还需要深入了解区块链的工作原理和应用场景。本文将介绍一种 DApp 系统开发的基本方案&am…

没学数模电可以玩单片机吗?

我们首先来看一下数电模电在单片机中的应用。数电知识在单片机中主要解决各种数字信号的处理、运算&#xff0c;如数制转换、数据运算等。模电知识在单片机中主要解决各种模拟信号的处理问题&#xff0c;如采集光照强度、声音的分贝、温度等模拟信号。而数电、模电的相互转换就…

华为云亮相KubeCon EU 2024,以持续开源创新开启智能时代

3月21日&#xff0c;在巴黎举办的云原生顶级峰会KubeCon EU 2024上 &#xff0c;华为云首席架构师顾炯炯在“Cloud Native x AI&#xff1a;以持续开源创新开启智能时代”的主题演讲中指出&#xff0c;云原生和AI技术的融合&#xff0c;是推动产业深刻变革的关键所在。华为云将…

报错:torch.distributed.elastic.multiprocessing.errors.ChildFailedError:

错误&#xff1a; torch.distributed.elastic.multiprocessing.errors.ChildFailedError: 这个主要是torch的gpu版本和cuda不适配 我的nvcc -V是11.8 torch使用的&#xff1a; pip install torch2.0.1 torchvision0.15.2 torchaudio2.0.2 --index-url https://download.pyt…

C#自定义最大化、最小化和关闭按钮

目录 1.资源文件 2.读取资源文件中的图片 3.WindowState属性 4. 示例 用户在制作应用程序时&#xff0c;为了使用户界面更加美观&#xff0c;一般都自己设计窗体的外观&#xff0c;以及窗体的最大化、最小化和关闭按钮。本例通过资源文件来存储窗体的外观&#xff0c;以及最…

【机器学习之---数学】随机游走

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 随机游走 1. 概念 1.1 例1 在你的饮食俱乐部度过了一个富有成效的晚上后&#xff0c;你在不太清醒的状态下离开了。因此&#xff0c;你会醉醺醺地在展…