1.视图控制器各个方法调用时机

2.选项卡(Tab Bar)和导航栏(Navigation Bar)

3.有无控制器的页面跳转

4.页面跳转隐藏底部选项卡

5.获取导航栏和状态栏高度,隐藏导航栏返回按钮、导航控制器,隐藏状态栏

6.模态视图的弹出动画和弹出风格

7.移除main.storyboard,解决总是进入ViewController

9.视图控制器不进入dealloc的几种原因

10.app锁屏相关

11.设置导航控制器字体颜色等

12.获得当前屏幕显示的ViewController

视图控制器各个方法调用时机

init:方法

在init方法中实例化必要的对象(遵从LazyLoad思想)
init方法中初始化ViewController本身
 
loadView:方法
这是当没有正在使用nib视图页面,子类将会创建自己的自定义视图层。绝不能直接调用
 
viewDidLoad:方法
在视图加载后被调用
 
viewWillAppear:方法
视图即将可见时调用
 
viewDidAppear:方法
视频完全过渡到屏幕上时调用
 
viewWillDisappear:方法
视图被驳回时调用,覆盖或以其他方式隐藏
 
viewDidDisappear:方法
视图被驳回后调用,覆盖或以其他方式隐藏
 
当A视图切换到B视图时,顺序流程
1.B视图的viewDidLoad
2.A视图的viewWillDisappear
3.B视图的viewWillAppear
4.A视图viewDidDisappear
5.B视图viewDidAppear
 
 
viewWillLayoutSubviews:方法
控制器的view将要布局子控件
 
viewDidLayoutSubviews:方法
控制器的view布局子控件完成
 
任何原因引起View的尺寸被改变;这期间系统可能会多次调用viewWillLayoutSubviews、viewDidLayoutSubviews 俩个方法
 

didReceiveMemoryWarning:方法

内存不足情况下视图控制器会收到这条消息;并不代表该应用占用了很多内存,也有可能是后台有很多程序占用了内存;收到警告后可以尝试释放内存(内存大户图像、视频、声音等)不是立刻需要的东西。(如果iOS认为你占用了很多内存是可以杀掉app的,比如在堆中存放20个视频等不合理使用内存的操作)

 

选项卡(Tab Bar)和导航栏(Navigation Bar)

//AppDelegate.h文件

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property(strong,nonatomic) UITabBarController *tabBarController;//底部选项卡控制器 @end

//AppDelegate.m文件

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; //消息控制器
MessageViewController *msgController=[[MessageViewController alloc] init];
UINavigationController *navMsg=[[UINavigationController alloc] initWithRootViewController:msgController];
//选项卡的图片样式以这种方式处理,避免图片无法完全显示
UITabBarItem *msgTabItem = [[UITabBarItem alloc]initWithTitle:@"消息" image:[[UIImage imageNamed:@"tab_message@3x.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"tab_message_select@3x.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
navMsg.tabBarItem=msgTabItem; //联系人控制器
ContactViewController *conController=[[ContactViewController alloc] init];
UINavigationController *navCon=[[UINavigationController alloc] initWithRootViewController:conController];
UITabBarItem *conTabItem = [[UITabBarItem alloc]initWithTitle:@"联系人" image:[[UIImage imageNamed:@"tab_ contact@3x.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"tab_ contact_select@3x.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
navCon.tabBarItem=conTabItem; //动态控制器
DynamicViewController *dynController=[[DynamicViewController alloc] init];
UINavigationController *navDyn=[[UINavigationController alloc] initWithRootViewController:dynController];
UITabBarItem *dynTabItem = [[UITabBarItem alloc]initWithTitle:@"动态" image:[[UIImage imageNamed:@"tab_ dynamic@3x.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"tab_ dynamic_select@3x.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
navDyn.tabBarItem=dynTabItem; self.tabBarController=[[UITabBarController alloc] init];
self.tabBarController.viewControllers=@[navMsg,navCon,navDyn];
self.tabBarController.selectedIndex=; //由于iPhone是单窗口程序,所以也就只有这么一个Window对象,而且是UIWindow,不是NSWindow。而根据文档上所说:这个是便捷方法,去使被使用对象的主窗口显示到屏幕的最前端。
[self.window makeKeyAndVisible];
return YES;
}

//底部选项卡显示未读消息

self.navigationController.tabBarItem.badgeValue = [NSString stringWithFormat:@"%ld",(long)count];

//应用图标消失未读消息

 [UIApplication sharedApplication].applicationIconBadgeNumber = count;

有无控制器的页面跳转

pushviewController是UINavigationController推到一个新viewController

//以栈的方式管理视图,各个视图的切换就是压栈和出栈操作,出栈后的视图会立即销毁。

[self.navigationController pushViewController:qqContactController animated:YES];//将视图压入栈内,后显示

//直接跳转到根控制器

 [self.navigationController popToRootViewControllerAnimated:YES];

//返回到上一层控制器(可以改变索引指定返回到前几个控制器)

[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:([self.navigationController.viewControllers count]-)] animated:YES];

//从栈中弹出该视图控制器(返回到上一层控制器)

[self.navigationController popViewControllerAnimated:YES];
 
presentViewController弹出模态视图(模态视图显示的时候不能对其他视图进行操作,例如UIAlertView)

//弹出模态视图

[self presentViewController:view animated:YES completion:nil];//弹出视图,不过是全屏不带navigation bar的。

//隐藏销毁模态视图

[self dismissViewControllerAnimated:YES completion:nil];

页面跳转隐藏底部选项卡

//在push到其他控制器要隐藏底部选项卡时,在需要跳转的控制器初始化方法下处理hidesBottomBarWhenPushed

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// 将hidesBottomBarWhenPushed属性设置如果为YES,当这个控制器push的时候,底部的Bar,比如Tabbar会滑走,也就是不会在push后的视图上显示出来,默认值为NO。
//这个属性只支持非自定义的Tabbar,也就是只支持原生Tabbar,
self.hidesBottomBarWhenPushed = YES;
}
return self;
}

//或者在跳转前设置

[ctr setHidesBottomBarWhenPushed:YES];

获取导航栏和状态栏高度,隐藏导航栏返回按钮、导航控制器,隐藏状态栏

CGRect rectStatus = [[UIApplication sharedApplication] statusBarFrame]; // 状态栏(statusbar)

float statusHeight=rectStatus.size.height; //状态栏高度

float navHeight=self.navigationController.navigationBar.frame.size.height; //导航栏高度

//隐藏导航控制器返回按钮

[self.navigationItem setHidesBackButton:YES]; 

//隐藏导航控制器

[self.navigationController setNavigationBarHidden:YES animated:NO];

//隐藏状态栏

- (BOOL)prefersStatusBarHidden
{
return YES;//隐藏为YES,显示为NO
}

模态视图的弹出动画和弹出风格

//弹出动画

typedef enum {
UIModalTransitionStyleCoverVertical = ,//视图从屏幕底部幻灯片,默认
UIModalTransitionStyleFlipHorizontal,//当前视图启动水平3 d从从右到左的翻转,导致新视图的暴露,就好像它是在前面的视图
UIModalTransitionStyleCrossDissolve,//视图淡出
UIModalTransitionStylePartialCurl,//从当前视图右下角卷起
} UIModalTransitionStyle;

//弹出风格

typedef enum {
UIModalPresentationFullScreen = ,//弹出VC充满全屏
UIModalPresentationPageSheet,//VC高度和当前屏幕高度相同,宽度和竖屏模式下屏幕宽度相同,剩余未覆盖区域将会变暗并阻止用户点击,这种弹出模式下,竖屏时跟UIModalPresentationFullScreen的效果一样,横屏时候两边则会留下变暗的区域。
UIModalPresentationFormSheet,//VC的高度和宽度均会小于屏幕尺寸,VC居中显示,四周留下变暗区域。
UIModalPresentationCurrentContext,//VC的弹出方式和该VC的父VC的方式相同。
} UIModalPresentationStyle;
这四种方式在iPad上面统统有效,但在iPhone和iPod touch上面系统始终已UIModalPresentationFullScreen模式显示presented VC。

//例:
    TestViewController *view=[[TestViewController alloc] init];
//弹出动画
// view.modalTransitionStyle=UIModalTransitionStyleCoverVertical;//视图从屏幕底部幻灯片,默认
view.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;//视图淡出
// view.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;//当前视图启动水平3 d从从右到左的翻转,导致新视图的暴露,就好像它是在前面的视图
// view.modalTransitionStyle=UIModalTransitionStylePartialCurl;//从当前视图右下角卷起
[self presentViewController:view animated:YES completion:nil];
 

移除main.storyboard,解决总是进入ViewController

在info.plist中删除下面一行

在工程中General中去掉关联

注意APPDelegate里面要加

[self.window makeKeyAndVisible];

视图控制器不进入dealloc的几种原因

 
dealloc方法之所以没有被调用时因为控制器的一个或多个强引用仍然在内存中,也就是当前控制器的计数器不为0
一般的几种原因:
  • 1.定时器没有被销毁, 解决方法:在viewWillDisappear需要把控制器用到的NSTimer销毁

    //调用一次定时器
    NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval: target:selfselector:@selector(hideView) userInfo:nil repeats:NO];
    //多次调用定时器,将reperats设置为YES
    NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval: target:selfselector:@selector(hideView) userInfo:nil repeats:YES]; //取消定时器,永久停止,需要将timer设置为nil
    [myTimer invalidate];
    myTimer = nil; //关闭定时器
    [myTimer setFireDate:[NSDate distantFuture]]; //开启定时器
    [myTimer setFireDate:[NSDate distantPast]];
  • 2.block块使用不当,因为block会对方法中的变量自动retain移除,请检查控制器中的block代码
  • 3.代理必须得用weak修饰,用strong强引用会导致计数器加1,无法释放内存。
  • 4.在getter方法里使用self,导致死循环

app锁屏相关

// 禁止自动锁屏
[UIApplication sharedApplication].idleTimerDisabled = YES; // 允许自动锁屏
[UIApplication sharedApplication].idleTimerDisabled = NO;

设置导航控制器字体颜色等

//设置标题
self.title=@"牛牛设置";
//设置标题颜色字体大小
[self.navigationController.navigationBarsetTitleTextAttributes:@{NSFontAttributeName:[UIFontsystemFontOfSize:],NSForegroundColorAttributeName:[UIColorcolorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:]}];
//修改导航栏背景色
[self.navigationController.navigationBar setBarTintColor:[UIColorcolorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:0.5]];
//更改返回按钮颜色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
//下一个视图的返回按钮文件会改变为下面设置的值
UIBarButtonItem *returnButtonItem = [[UIBarButtonItem alloc] init];
returnButtonItem.title = @"";
self.navigationItem.backBarButtonItem = returnButtonItem;  

获得当前屏幕显示的ViewController

/**
获得当前屏幕显示的ViewController
适用范围tabbar的子视图都是NavigationController,
或有NavigationController的视图控制器
@return 返回当前正在显示的视图控制器
*/
- (UIViewController *)getCurrentVC{
UIViewController *result = nil;
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
//app默认windowLevel是UIWindowLevelNormal(默认的水平。使用这个级别的大部分内容,包括为您的应用程序的主窗口。),如果不是,找到UIWindowLevelNormal的
if (window.windowLevel != UIWindowLevelNormal)
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows)
{
if (tmpWin.windowLevel == UIWindowLevelNormal)
{
window = tmpWin;
break;
}
}
}
id nextResponder = nil;
UIViewController *appRootVC=window.rootViewController;
// 如果是present上来的appRootVC.presentedViewController 不为nil
if (appRootVC.presentedViewController) {
nextResponder = appRootVC.presentedViewController;
}else if(appRootVC.childViewControllers){
//如果有子视图控制器
while (appRootVC.childViewControllers>) {
if ([appRootVC isKindOfClass:[UINavigationController class]]) {
appRootVC=[appRootVC.childViewControllers lastObject];
break;
}
else if ([appRootVC isKindOfClass:[UITabBarController class]]){
UITabBarController * tabbar = (UITabBarController *)appRootVC;
appRootVC=(UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex];
}
else{
for (int i=; i<appRootVC.childViewControllers.count; i++) {
//isViewLoaded 表示已经视图被加载过 view.window表示视图正在显示
if ([appRootVC.childViewControllers objectAtIndex:i].isViewLoaded && [appRootVC.childViewControllers objectAtIndex:i].view.window) {
appRootVC=[appRootVC.childViewControllers objectAtIndex:i];
break;
}
}
}
}
nextResponder=appRootVC;
}else{
UIView *frontView = [[window subviews] objectAtIndex:];
//nextResponder返回接收器的下一个应答器(见UIResponder+Router进行事件分发)
nextResponder = [frontView nextResponder];
}
result = nextResponder;
return result;
}

iOS,视图控制器相关(UIViewController)的更多相关文章

  1. iOS开发 ~应用程序设计理念:视图控制器(UIViewController)、视图(UIView)

    应用程序设计理念:视图控制器(UIViewController).视图(UIView) 利用视图控制器(底层)管理视图(外观),一对一 1.视图的作用:负责显示的外观 2.视图控制器的作用:创建界面. ...

  2. iOS 视图控制器转场详解

    iOS 视图控制器转场详解 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标有了大幅度的增长,多谢唐巧前辈的推荐.有些人问我相关的问题 ...

  3. iOS视图控制器的生命周期

    今天面试有一道面试题因为回答不好,因为也不经常涉及所以有点模糊,我选择了最保守的回答,没有展开写出我对这个问题的理解. 问题:IOS 开发 loadView 和 viewDidLoad 的区别? 经过 ...

  4. iOS 视图控制器 (内容根据iOS编程编写)

    视图控制器是  UIViewController 类或其子类对象.每个视图控制器都负责管理一个视图层次结构,包括创建视图层级结构中的视图并处理相关用户事件,以及将整个视图层次结构添加到应用窗口. 创建 ...

  5. 学习笔记:iOS 视图控制器(UIViewController)剖析

    转自:http://www.cnblogs.com/martin1009/archive/2012/06/01/2531136.html 视图控制器在iOS编程中占据非常重要的位置,因此我们一定要掌握 ...

  6. 笔记-iOS 视图控制器转场详解(上)

    这是一篇长文,详细讲解了视图控制器转场的方方面面,配有详细的示意图和代码,为了使得文章在微信公众号中易于阅读,seedante 辛苦将大量长篇代码用截图的方式呈现,另外作者也在 Github 上附上了 ...

  7. iOS(视图控制器转场)

    转场需要提供转场代理,不使用默认的代理则需要自己实现代理方式,有UINavigationController.UITabBarController.UIViewController三种代理,实现以下三 ...

  8. iOS 视图控制器转场动画/页面切换效果/跳转动画 学习

    一 学习 在 UINavigationController 中 push 和 pop 的转场效果  (基于iOS7 以上的转场方式) 经过学习了解到,重点分三块: (1)pushAnimation:  ...

  9. 和iPhone有关的视图控制器:UIViewController、UITabBarController、UINavigationController及其混合用法

    iPhone中的view视图是应用程序对于数据最直观.最直接的呈现方式,如下是我在学习了iPhone中的视图控制器以及由其衍生的特殊子类的总结,希望对那些初学者有所帮助: UIViewControll ...

随机推荐

  1. NOIP 2005 等价表达式 (TYVJ P1060)

    做题记录: 2016-08-10 23:35:09 背景 NOIP2005 提高组 第四道 描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代 ...

  2. URAL 1031. Railway Tickets(spfa)

    题目链接 不知为何会在dp里呢...INF取小了,2Y. #include <cstring> #include <cstdio> #include <string> ...

  3. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

  4. SVN错误:Attempted to lock an already-locked dir

    在eclipse里提交和更新文件是报错: Attempted to lock an already-locked dir svn: Working copy 'F:\workspace\WebFram ...

  5. 深入浅出 - Android系统移植与平台开发(四)- Android启动流程

    作者:唐老师,华清远见嵌入式学院讲师. 一.Android init进程启动 还是从Linux的启动开始吧.Linux被bootloader加载到了内存之后,开始运行,在初始化完 Linux运行环境之 ...

  6. flume-ng配置文档简单说明

    1.配置文件现状 1.1 Flume数据接收端 IP地址:54.0.95.67 功能:接收各个端口发来的数据. 启动方式:进入目录 /usr/local/flume/*bin 在终端运行 ./rece ...

  7. java mail(发送邮件--163邮箱)

    package com.util.mail; /** * 发送邮件需要使用的基本信息 */ import java.util.Properties; public class MailSenderIn ...

  8. 浅析-博客Ping服务

    简介:PING服务是博客站点向博客目标网站.搜索引擎等发出的博客内容更新通知服务,然后博客目标网站.搜索引擎就会及时的索引.收录以及传播您的博客内容. PING原理 PING 服务是博客站点向博客目标 ...

  9. 【腾讯云】腾讯云服务器搭建ftp服务器

    一.硬件描述 1.1 云服务器:腾讯云 云主机 操作系统:Ubuntu Server 14.04.1 LTS 32位 CPU:1核 内存:1GB 系统盘:20GB(本地磁盘) 数据盘:0GB 公网带宽 ...

  10. 二分查找算法(JAVA)

    1.二分查找又称折半查找,它是一种效率较高的查找方法. 2.二分查找要求:(1)必须采用顺序存储结构 (2).必须按关键字大小有序排列 3.原理:将数组分为三部分,依次是中值(所谓的中值就是数组中间位 ...