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

news2024/9/23 3:24:33

文章目录

    • 一、前言
    • 二、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 = .darkGray
        present(vc, animated: true)
    }
    @objc func presentNC() {
        let vc = ViewController()
        vc.view.backgroundColor = .gray
        let nc = UINavigationController(rootViewController: vc)
        present(nc, animated: true)
    }
    @objc func presentTC() {
        let tc = MyTabbarController()
        tc.view.backgroundColor = .blue
        let nc = UINavigationController(rootViewController: tc)
        present(nc, animated: true)
    }
    @objc func presentPC() {
        let pc = MyPageViewController()
        pc.view.backgroundColor = .red
        let nc = UINavigationController(rootViewController: pc)
        present(nc, animated: true)
    }
    @objc func pushVC() {
        let vc = ViewController()
        vc.view.backgroundColor = .purple
        if 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 = .gray
        let vc1 = ViewController()
        vc1.tabBarItem.image = UIImage(named: "diamond")
        vc1.tabBarItem.title = "tab1"
        vc1.view.backgroundColor = .red
        let vc2 = ViewController()
        vc2.tabBarItem.image = UIImage(named: "diamond")
        vc2.tabBarItem.title = "tab2"
        vc2.view.backgroundColor = .blue
        let vc3 = ViewController()
        vc3.tabBarItem.image = UIImage(named: "diamond")
        vc3.tabBarItem.title = "tab3"
        vc3.view.backgroundColor = .purple
        self.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 = self
        let vc1 = ViewController()
        vc1.view.backgroundColor = .red
        let vc2 = ViewController()
        vc2.view.backgroundColor = .blue
        let vc3 = ViewController()
        vc3.view.backgroundColor = .purple
        let vc4 = ViewController()
        vc4.view.backgroundColor = .gray
        vcs = [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) - 1
        if i < 0 {
            return nil
        }
        return vcs[i]
    }
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let i = (vcs.firstIndex(of: viewController as! ViewController) ?? 0) + 1
        if i >= vcs.count {
            return nil
        }
        return vcs[i]
    }
}

六、拓展阅读

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

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

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

相关文章

岭师大数据技术原理与应用-序章-软工版

HeZaoCha-CSDN博客 序章—软工版 一、环境介绍1. VMware Workstation Pro2. CentOS3. Java4. Hadoop5. HBase6. MySQL7. Hive 二、系统安装1. 虚拟网络编辑器2. 操作系统安装 三、结尾 先说说哥们写这系列博客的原因&#xff0c;本来学完咱也没想着再管部署这部分问题的说&…

第二证券今日投资参考:低空经济迎利好 自动驾驶商业化提速

昨日&#xff0c;两市股指盘中弱势震动&#xff0c;午后加快下探&#xff0c;沪指失守3000点大关&#xff0c;深成指、创业板指跌超2%&#xff1b;到收盘&#xff0c;沪指跌1.26%报2993.14点&#xff0c;深成指跌2.4%报9222.47点&#xff0c;创业板指跌2.81%报1789.82点&#x…

目前常见的搜索引擎有哪些?

常见的搜索引擎可以分为两类&#xff1a;全网搜索类和平台内搜索。 全网搜索类是指可以在互联网范围内进行搜索的引擎&#xff0c;它们提供了广泛的搜索结果&#xff0c;包括网页、图片、视频、新闻等各种类型的内容。以下是一些常见的全网搜索引擎&#xff1a; 百度&#xff…

idea类已经存在却报错

一句话导读 在idea中导入新的项目&#xff0c;很多类都飘红报错&#xff0c;mvn compile可以通过&#xff0c;可能是因为idea缓存问题导致。 由于这个项目是由老项目复制过来后&#xff0c;再继续开发新的功能&#xff0c;很多同事导入后&#xff0c;都爆出新的类找不到。而编译…

linux nginx配置ssl, 实现https+ip访问

mkdir sslZhengShu openssl req -newkey rsa:2048 -nodes -keyout ca.key -out ca.csr openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr 和之前输入一样即可 …

反序列化动态调用 [NPUCTF2020]ReadlezPHP1

在源代码上看到提示 访问一下看看 代码审计一下 <?php #error_reporting(0); class HelloPhp {public $a;public $b;public function __construct(){$this->a "Y-m-d h:i:s";$this->b "date";}public function __destruct(){$a $this->a;…

【Go】结构体中Tag标识

https://blog.csdn.net/weixin_45193103/article/details/123876319 https://blog.csdn.net/qq_49723651/article/details/122005291 https://juejin.cn/post/7005465902804123679 学一点&#xff0c;整一点&#xff0c;基本都是综合别人的&#xff0c;弄成我能理解的内容 Tag定…

ubuntu编译OpenCV and seetaFace2

opencv opencv-4.5.2 opencv_contrib-4.5.2 SeetaFace2 SeetaFace2-master https://github.com/seetafaceengine 指定安装目录&#xff0c;和OpenCV放一个目录下了 安装前 安装 安装后 Qt安装 Windows下 Linux下 报错1 原因&#xff1a; 报错…

CMS(内容管理系统)

一、系统的编写可以在开源网站上下载一个相关项目&#xff0c;然后做2次开发 企业建站系统:MetInfo(米拓)、蝉知、SiteServer CMs等; B2C商城系统:商派Shopex、ECshop、HiShop、XpShop等; 门户建站系统:DedeCMS(织梦)、帝国CMS、PHPCMS、动易、CmsTop等; 博客系统:WordPres…

【JavaWeb】Day18.Vue组件库Element

什么是Element Element&#xff1a;是饿了么团队研发的&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。组件&#xff1a;组成网页的部件&#xff0c;例如 超链接、按钮、图片、表格、表单、分页条等等。官网&#xff1a;Element - The worlds…

Capture One Pro 22 for Mac/win:重塑RAW图像处理的艺术

在数字摄影的世界里&#xff0c;RAW图像处理软件无疑是摄影师们手中的魔法棒&#xff0c;而Capture One Pro 22无疑是这一领域的璀璨明星。这款专为Mac和Windows系统打造的图像处理软件&#xff0c;以其出色的性能、丰富的功能和极致的用户体验&#xff0c;赢得了全球摄影师的广…

C++优先队列——priority_queue,函数对象,labmda表达式,pair等

头文件&#xff1a;#include<queue> 内部使用堆来实现&#xff0c;在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。 用法&#xff1a; priority_queue<int, vector<int>, greater<int>>q; 第一个参数为堆中存储的元素。 …

Rust控制台输出跑马灯效果,实现刷新不换行,实现loading效果

要在 Rust 中实现控制台刷新而不换行&#xff0c;以实现类似 "loading" 状态的效果&#xff0c;你可以使用 \r&#xff08;回车符&#xff09;来覆盖上一行的内容。 use std::io::{self, Write}; use std::thread; use std::time::Duration;fn main() {let loading_…

使用Jenkins打包时执行失败,但手动执行没有问题如ERR_ELECTRON_BUILDER_CANNOT_EXECUTE

具体错误信息如&#xff1a; Error output: Plugin not found, cannot call UAC::_ Error in macro _UAC_MakeLL_Cmp on macroline 2 Error in macro _UAC_IsInnerInstance on macroline 1 Error in macro _If on macroline 9 Error in macro FUNCTION_INSTALL_MODE_PAGE_FUNC…

国外的Java面试题和国内的相比谁更卷

前言 有很多朋友很好奇国外的Java面试题长啥样&#xff0c;今天我们就去找5道国外的面试来和国内的对比一下看看谁难一些&#xff01; 面试题分享 1. Is Java Platform Independent if then how?&#xff08; Java平台是独立的吗&#xff1f;&#xff09; Yes, Java is a…

分享react+three.js展示温湿度采集终端

前言 气象站将采集到的相关气象数据通过GPRS/3G/4G无线网络发送到气象站监测中心&#xff0c;摆脱了地理空间的限制。 前端&#xff1a;气象站主机将采集好的气象数据存储到本地&#xff0c;通过RS485等线路与GPRS/3G/4G无线设备相连。 通信&#xff1a;GPRS/3G/4G无线设备通…

Cocos2dx-lua ScrollView[三]高级篇

一.概述 本文缩写说明&#xff1a;sv ScrollView, cell代表ScrollView的一个子节点 本文介绍sv的一种封装类库&#xff0c;来实现快速创建sv&#xff0c;有如下几个优点&#xff1a; 1.item的位置通过参数控制&#xff0c;提高开发效率 2.免去了调用sv的API&#xff0c;提…

[flink] flink macm1pro 快速使用从零到一

文章目录 快速使用 快速使用 打开 https://flink.apache.org/downloads/ 下载 flink 因为书籍介绍的是 1.12版本的&#xff0c;为避免不必要的问题&#xff0c;下载相同版本 解压 tar -xzvf flink-1.11.2-bin-scala_2.11.tgz启动 flink ./bin/start-cluster.sh打开 flink web…

【JavaSE】String类详解

目录 前言 1. 什么是String类 1.1 String的构造 1.2 String类的基本操作&#xff1a;打印、拼接、求字符串长度 2. String类的常用方法 2.1 字符串查找 2.2 字符串替换 2.3 字符串拆分 2.4 字符串截取 2.5 字符串和其他类型的转换 2.6 去除字符串左右两边的空格 3.…

大模型 智能体 智能玩具 智能音箱 构建教程 wukong-robot

视频演示 10:27 一、背景 继上文《ChatGPT+小爱音响能擦出什么火花?》可以看出大伙对AI+硬件的结合十分感兴趣,但上文是针对市场智能音响的AI植入,底层是通过轮询拦截,算是hack兼容,虽然官方有提供开发者接口,也免不了有许多局限性(比如得通过特定指令唤醒),不利于我…