UIApplication
每一个应用都有自己的UIApplication对象,而且是单例的
通过[UIApplication sharedApplication]可以获得这个单例对象
一个iOS程序启动后创建的第一个对象就是UIApplication对象
单例对象的获取
UIApplication *app = [UIApplicationsharedApplication];
隐藏状态栏
// 1、隐藏状态栏,ios7以后默认是由控制器控制的,如果要用UIApplication控制请在info.plist中设置一个参数
// UIViewController-based status bar system NO;
[app setStatusBarHidden:YES];
显示提醒框
// 2、引用提醒框,IOS8以后必须注册通知才能使用
app.applicationIconBadgeNumber = 14;
UIUserNotificationSettings *setting = [UIUserNotificationSetting ssettingsForTypes:UIUserNotificationTypeBadgecategories:nil];
// 注册通知
[app registerUserNotificationSettings:setting ];
设置网络加载状态,在状态栏显示
// 3、设置联网状态,在状态栏显示
app.networkActivityIndicatorVisible = YES;
打开网页或通话面板
// 4、打开网页,打电话,发邮件等
// URL : 协议头+域名(路径) http/ftp/tel等
// 系统通过协议头来判断具体要打开何种软件
UIApplication *app = [UIApplicationsharedApplication];
NSURL *url = [NSURLURLWithString:@"http://www.qq.com"]; // http 会打开Safari
[app openURL: url];
info.plist文件
可以通过mainBundle 获取info.plist的一些属性。下面是一些已经定义好的。
@property (readonly, copy) NSString *bundleIdentifier;
@property (readonly, copy) NSDictionary *infoDictionary;
@property (readonly, copy) NSDictionary *localizedInfoDictionary;
常见属性(红色部分是用文本编辑器打开时看到的key)
Localiztion native development region(CFBundleDevelopmentRegion)-本地化相关
Bundle display name(CFBundleDisplayName)-程序安装后显示的名称,限制在10-12个字符,如果超出,将被显示缩写名称
Icon file(CFBundleIconFile)-app图标名称,一般为Icon.png
Bundle version(CFBundleShortVersionString)-应用程序的版本号,每次往App Store上发布一个新版本时,需要增加这个版本号
Main storyboard file base name(NSMainStoryboardFile)-主storyboard文件的名称
Bundle identifier(CFBundleIdentifier)-项目的唯一标识,部署到真机时用到
pch文件
项目的Supporting files文件夹下面有个“工程名-Prefix.pch”文件,也是一个头文件
pch头文件的内容能被项目中的其他所有源文件共享和访问
一般在pch文件中定义一些全局的宏
在pch文件中添加下列预处理指令,然后在项目中使用Log(…)来输出日志信息,就可以在发布应用的时候,一次性将NSLog语句移除(在调试模式下,才有定义DEBUG)
#ifdef DEBUG
#define Log(...) NSLog(__VA_ARGS__) // … 表示宏可变参数,__VA_ARGS__ 表示函数可变参数
#else
#define Log(...)
#endif
AppDelegate
每一个工程都会自动生成一个代理文件,这个代理文件的一些方法如下,还有调用顺序。
// 1、启动完成后调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
// 3、应用程序失去焦点后调用,再进入后台
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
// 4、应用进入后台调用,接电话,锁屏,按下home建等操作
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
// 5、应用进入前台后调用,先进入前台再获得焦点 2
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
// 2、应用获得焦点,可与用户交互
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
// 应用终止运行会调用,实际上得调用也无法测试
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application‘s managed object context before the application terminates.
[self saveContext];
}
由前台进入后天过程:先失去焦点,再进入后台。
有后台进入前台过程:先进入前台,再获得焦点。
main.m文件
每个程序都要有个main函数,ios也一样。默认位置在Supporting Files文件下。
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegateclass]));
}
}
在Xcode中 main函数只调用了一个方法 UIApplicationMain 。
UIApplicationMain 方法做了一些初始化的操作:
1、第三个参数:创建一个 UIApplication 对象,默认nil就返回 UIAplication 对象
2、第四个参数:创建一个 UIApplicationDelegate 代理对象,然后设置UIApplication.delegate = UIApplicationDelegate
3、设置一个主循环,可保持程序一直出去运行状态,开始接受事件
4、加载info.plist ,然后加载main.storyboard
main.storyboard 的加载过程
1、初始化一个窗口Window
2、加载main.storyboard 并且初始化控制器
3、设置view的rootViewController并显示到屏幕
真正的加载过程
在代理方法中使用,程序启动完成后创建窗口并显示。
大概过程如下:
// 1、创建窗口
self.window = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];
self.window.backgroundColor = [UIColorredColor];
// 2、创建一个控制器,并指定window的父控制器
UIViewController *vc = [[UIViewController alloc] init];
self.window.rootViewController = vc;
// 3、显示窗口
[self.window makeKeyAndVisible];
关于第二步创建一个控制器,还有几种方法
方法1:使用代码
// 方法1: 代码
UIViewController *vc = [[UIViewControlleralloc] init];
self.window.rootViewController = vc;
方法2:使用storyboard
// 方法2: storyboard创建
// 参数bundle为nil时指 mainBundle
UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
// 默认加载箭头指向的那个控制器
UIViewController *vc1 = [story instantiateInitialViewController];
// 使用标识加载控制器,可在storyboard 里进行设置
UIViewController *vc2 = [story instantiateViewControllerWithIdentifier:@"green"];
self.window.rootViewController = vc1;
方法3:使用xib
// 方法3: xib创建
/* 注意事项
通过xib创建控制器的view
一定要描述xib的文件拥有者是控制器,也就是说这个xib是用来描述控制器
*/
UIViewController *vc3 = [[ViewController alloc] initWithNibName:@"abc" bundle:nil];
//UIViewController *vc3 = [[ViewController alloc] init];
/**
加载跟类名相同的xib
如果描述控制器View的xib跟控制器的类名相同,就会去加载
只有控制器的init方法底层会调用initWithNibName:bundle:
只要通过initWithNibName:bundle:初始化控制器,并且nibName为nil,就会执行以下几步。
SLQViewController类型
1.寻找有没有跟控制器类名同名但是不带Controller的xib,如果有就会去加载(XXX.xib)
2.寻找有没有跟控制器类名同名的xib,如果有就会去加载(SLQViewController.xib)
3.如果都没有找到,创建空的view,
*/
UIViewController *vc4 = [[ViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = vc3;
通过xib创建系统会做很多判断,一定要注意。
默认创建的空view是近乎透明的
// 2、创建一个控制器
// 创建UIViewController控制器,控制器的view并没有创建
// 控制器的view懒加载:第一次使用的时候才会去加载,并不是创建UIViewController控制器的时候去加载
UIViewController *vc = [[UIViewControlleralloc] init];
// vc.view.backgroundColor = [UIColor clearColor]; //类似设置clearColor属性
// vc.view.alpha = 1;
// 默认创建的空view是近乎透明的,不能穿透。
self.window.rootViewController = vc;
自定义view需要注意的地方
在控制器中的loadView方法中自定义自己的view
// 默认loadView可以加载storyboard和xib描述的控制器的view
// 如果想自定义view,可以在这里进行操作
- (void)loadView
{
// 如果控制器是窗口的根控制器就可以不用设置尺寸
self.view = [[UIView alloc] initWithFrame:CGRectZero];
self.view.backgroundColor = [UIColoryellowColor];
}
// view的getter方法类似下面
//- (UIView *)view
//{
// if (_view == nil) {
// [self loadView];
// 。。。。。
// [self viewDidLoad];
// }
// return _view;
//}
// 在viewDidLoad中打印控制器的尺寸不准确,通常在viewDidAppear
// 控制器的view加载完成的时候调用
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%@",NSStringFromCGRect(self.view.bounds));
}
UINavigation - 导航控制器
创建过程
// 1、创建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColorredColor];
// 2、创建控制器
UIViewController *vc = [[FirstViewControlleralloc] init];
// UINavigationController 初始化
// 导航控制器也需要一个根控制器
// 默认导航控制器把根控制器的view添加到导航控制器的view上
UINavigationController *nav = [[UINavigationControlleralloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
// 3、显示窗口
[self.window makeKeyAndVisible];
导航控制的使用,主要是以下几个方法。
UINavigationController以栈的形式保存子控制器
@property(nonatomic,copy) NSArray *viewControllers;
@property(nonatomic,readonly) NSArray *childViewControllers;
使用push方法能将某个控制器压入栈
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
使用pop方法可以移除控制器
将栈顶的控制器移除
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
回到指定的子控制器
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
回到根控制器(栈底控制器)
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
添加跳转界面
首先控制器的头文件
然后创建一个控制器
最后入栈。
- (IBAction)jumpToSecond:(id)sender
{
// 创建控制器
UIViewController *vc = [[SecondViewControlleralloc] init];
// 入栈
[self.navigationControllerpushViewController:vc animated:YES];
// 修改顶部标题
self.navigationItem.title = @"上一页";
}
回到上一个View中
- (IBAction)jumpToFirst:(id)sender
{
// 弹出最底部的view
[self.navigationControllerpopToRootViewControllerAnimated:YES];
}
- (IBAction)jumpToPre:(id)sender
{
// 弹出最顶部的view
[self.navigationControllerpopViewControllerAnimated:YES];
}