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

容器还可以嵌套,比如把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的导航栏。

在这里插入图片描述

示例代码如下:

#import "MeetingVC.h"

@property (nonatomic, strong) MeetingVC \*meetVC;
@property (nonatomic, strong) BPGeneralContainerWebPageViewController \*webPageVC;

// 视图入栈
self.meetVC = [[MeetingVC alloc] init];
[self.navigationController pushViewController:self.meetVC animated:YES];

// 视图出栈
[self.webPageVC.navigationController popViewControllerAnimated:YES];

其中,​self.navigationController是当前页面。

3.1 UINavigationController导航控制器初始化 & 导航控制器栈的push和pop跳转理解

(1)导航控制器初始化的时候一般都有一个根视图控制器导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面。在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界面,也就是用户看到的界面。

(2)我们需要把导航控制器加载到APP中,需要把这个导航控制器设置为window的根视图控制器(都是控制器类,可以赋值),这样就相当于加载到了window里。

(3)我们要在栈中新增或者删除一个视图控制器,就需要得到导航控制器,一般在栈中的所有视图控制器都有一个self.navigationController,意思是我的导航控制器,也就是这个视图控制器所在的导航控制器,这样就拿到了导航控制器

(4)栈中新增视图控制器pushViewController,其实就是push进去一个,这样对于用户而言就是打开一个新界面了。

(5)栈中删除一个视图控制器popViewControllerAnimated,当然这个pop只能pop最上面的那个,对于用户而言相当于从当前视图回到上一级视图。

(6)其实这个push和pop对于用户而言都是打开和跳转页面的一个操作。而pop有更多地操作方法,如一下子pop掉只剩下一个根视图控制器,那么就相当于从好几层直接回到最原始的主页面。也可以指定pop几个,以跳转到指定的页面。

(7)最重要的应该就是这个push和pop方法,而pop有很多种,这个理解后就不难记忆。

如果一级一级的返回示例如下:

[self.navigationController popViewControllerAnimated:Yes];

返回根页面示例如下 :

self.navigationController popToRootViewController]

返回指定的某级页面示例如下:

第N级

[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:N] animated:YES];

或指定控制器

//遍历控制器for (UIViewController \*controller in self.navigationController.viewControllers) 

{

	 if ([controller isKindOfClass:[你要跳转到的Controller class]]) {  
	
		[self.navigationController popToViewController:controller animated:YES]; 
	
}}

一次性pop到上上一级

// 获取当前视图层级
int index = (int)[[self.navigationController viewControllers]indexOfObject:self];  
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:(index -2)] animated:YES];

在这里插入图片描述

3.2 将子控制器添加到导航控制器中的四种方式

第一种方式:

  1. 创建一个导航控制器:
UINavigationController \*nav=[[UINavigationController alloc]init];

2.设置导航控制器为window的根视图:

self.window.rootViewController=nav;

  1. 添加:
YYOneViewController  \*one = [[YYOneViewController alloc] init];

[nav pushViewController:one animated:YES];

第二种方式:

  1. 创建一个导航控制器:
UINavigationController \*nav=[[UINavigationController alloc]init];

  1. 设置导航控制器为window根视图:
self.window.rootViewController=nav;

  1. 添加:
YYOneViewController  \*one = [[YYOneViewController alloc] init];

[nav addChildViewController:one];

第三种方式:

  1. 创建一个导航控制器:
UINavigationController \*nav=[[UINavigationController alloc]init];

  1. 设置导航控制器为window根视图:
self.window.rootViewController=nav;

  1. 添加:
YYOneViewController \*one = [[YYOneViewController alloc] init];

nav.viewControllers=@[one];(添加到导航控制器的栈中)

说明:nav.childViewControllers属性是只读的,因此不能像下面这样写。nav.childViewControllers = @[one];

第四种方式:

YYOneViewController \*one=[[YYOneViewController alloc]init];

UINavigationController \*nav=[[UINavigationController alloc]initWithRootViewController:one];

完整示例代码如下:

#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication \*)application didFinishLaunchingWithOptions:(NSDictionary \*)launchOptions {
      //1.窗口初始化
      self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
      
      //2.视图控制器
      ViewController \*vc = [[ViewController alloc] init];
      //VC.view.backgroundColor = [UIColor cyanColor];
      //[self.window makeKeyAndVisible]; 
      
      //3.创建一个导航控制器对象,并将rootVC作为导航控制器的根视图控制器
      UINavigationController \*navCtr = [[UINavigationController alloc] initWithRootViewController:vc];
      //简易更改外观
      [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navBg.png"] forBarMetrics:UIBarMetricsDefault];
      
      //4.将导航控制器设置为根视图控制器
      self.window.rootViewController =navCtr;
      //5.关键步骤:让当前窗口作为keyWindow(唯一性)主窗口并且可见
      [self.window makeKeyAndVisible];
      
      return YES;
  }  
 @end

ViewController.m文件如下:

#import "ViewController.h"
#import "FirstViewController.h"

@interface ViewController ()
@end

@implementation ViewController
  /\*
 导航控制器->视图控制器->视图
 当根控制器设置为导航控制器时 
 UINavigationController 是用于构建分层应用程序的主要工具,主要采用栈形式来实现视图。任何类型的视图控制器都可放入栈中。在设计导航控制器时需要指定根视图即用户看到的第一个视图。根视图控制器是被导航控制器推入到栈中的第一个视图控制器。当用户查看下一个试图时,栈中将加入一个新的视图控制器,它所控制的视图将展示给用户。我们可以通过导航按钮来操作分层的应用程序,用它来控制视图的推入或推出


### js基础
1)对js的理解?
2)请说出以下代码输出的值?
3)把以下代码,改写成依次输出0-9
4)如何区分数组对象,普通对象,函数对象
5)面向对象、面向过程
6)面向对象的三大基本特性
7)XML和JSON的区别?
8)Web Worker 和webSocket?
9)Javascript垃圾回收方法?
10)new操作符具体干了什么呢?
11)js延迟加载的方式有哪些?
12)WEB应用从服务器主动推送Data到客户端有那些方式?

![js基础.PNG](https://img-blog.csdnimg.cn/img_convert/781eb0ec9ae8c4b885f4c152d30d26f0.webp?x-oss-process=image/format,png)

![前16.PNG](https://img-blog.csdnimg.cn/img_convert/d4657e9a221e701982cd0438ac1c3233.webp?x-oss-process=image/format,png)

时,栈中将加入一个新的视图控制器,它所控制的视图将展示给用户。我们可以通过导航按钮来操作分层的应用程序,用它来控制视图的推入或推出


### js基础
1)对js的理解?
2)请说出以下代码输出的值?
3)把以下代码,改写成依次输出0-9
4)如何区分数组对象,普通对象,函数对象
5)面向对象、面向过程
6)面向对象的三大基本特性
7)XML和JSON的区别?
8)Web Worker 和webSocket?
9)Javascript垃圾回收方法?
10)new操作符具体干了什么呢?
11)js延迟加载的方式有哪些?
12)WEB应用从服务器主动推送Data到客户端有那些方式?

[外链图片转存中...(img-BaEnXaM1-1718172946308)]

[外链图片转存中...(img-DABeJZLR-1718172946309)]

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值