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

JavaScript

  • js的基本类型有哪些?引用类型有哪些?null和undefined的区别。

  • 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

  • Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?

  • JS常见的dom操作api

  • 解释一下事件冒泡和事件捕获

  • 事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?

  • 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

  • this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

  • call,apply,bind

  • 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

  • 创建对象的多种方式

  • 实现继承的多种方式和优缺点

  • new 一个对象具体做了什么

  • 手写Ajax,XMLHttpRequest

  • 变量提升

  • 举例说明一个匿名函数的典型用例

  • 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?

  • attribute和property的区别

  • document load和document DOMContentLoaded两个事件的区别

  • JS代码调试

  • 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

      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`的导航栏。


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a4eb27fecdee484481e55c4fd6d176b3.png)


示例代码如下:



#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];


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a0f24c35663c49498e667777b0e62574.png)


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


**第一种方式:**


1. 创建一个导航控制器:



UINavigationController *nav=[[UINavigationController alloc]init];


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



self.window.rootViewController=nav;


3. 添加:



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

[nav pushViewController:one animated:YES];


**第二种方式:**


1. 创建一个导航控制器:



UINavigationController *nav=[[UINavigationController alloc]init];


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



self.window.rootViewController=nav;


3. 添加:



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

[nav addChildViewController:one];


**第三种方式:**


1. 创建一个导航控制器:



UINavigationController *nav=[[UINavigationController alloc]init];


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



self.window.rootViewController=nav;


3. 添加:



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

  • (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @“ViewController”;
    self.view.backgroundColor = [UIColor purpleColor];

    UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(myAdd)];
    self.navigationItem.rightBarButtonItem = rightBtn;

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
    btn.frame = CGRectMake(90, 90, 200, 50);
    [btn setTitle:@“Go to the next” forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    btn.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:btn];

    [btn addTarget:self action:@selector(btnPushClick) forControlEvents:UIControlEventTouchUpInside];

}

#pragma mark - 自定义方法

#pragma mark -UIBarButtonItem的右耳目关联方法

  • (void)myAdd
    {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@“Touch” message:@“添加某种功能” delegate:self cancelButtonTitle:@“Good Job” otherButtonTitles: nil];
    [alert show];
    }

#pragma mark - 按钮关联方法-压栈

  • (void)btnPushClick

最后

全网独播-价值千万金融项目前端架构实战

从两道网易面试题-分析JavaScript底层机制

RESTful架构在Nodejs下的最佳实践

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

一线互联网企业如何初始化项目-做一个自己的vue-cli

思维无价,看我用Nodejs实现MVC

代码优雅的秘诀-用观察者模式深度解耦模块

前端高级实战,如何封装属于自己的JS库

VUE组件库级组件封装-高复用弹窗组件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值