035-多控制器管理(1)-iOS笔记

学习目标

1.【掌握】UIPickerView简介

2.【理解】UIPickerView显示字符串

3.【理解】UIPickerView显示自定义View

4.【掌握】UIDatePicker简介

5.【掌握】UIPickerView基本使用方法

6.【了解】项目中的常见文件

7.【理解】App启动原理

一、UIPickerView简介

UIPickerView也是一个iOS开发中常用的控件,适用于让用户选择少量数据,比如设置出生日期、城市、国家等。UIPickerView在iOS6和iOS7后的风格有所改变,之前是拟物化,现在变为扁平化了。他的用法和我们之前学习的UITableView类似,都需要用到数据源和代理来显示数据和监听事件。

UIPickerView的注意点
1.在ios8之前,UIPickerView的高度是(162)固定的,不能被修改。在 ios8后,它的高度就可以修改了。

2.下面这个方法的重用 view 在 ios6之后就一直为空。如果需要适配 ios6之前的系统,为了性能考虑,应该将这个 view 利用起来。

pickerView的高度设置

如果没有主动设置高度,或者设置为0。则高度默认值216

如果设置的高度大于0且小于180,则高度默认值162

如果设置的高度大于等于180且小于216,怎么高度默认值为180

pickerView 的宽度设置

初始化时没有给定宽度,或者给定的宽度为0,则宽度默认等于屏幕的宽度。

给定了一个不为大于0的宽度,则宽度就等于给定的值。

二、UIPickerView显示字符串

UIPickerView可以显示纯文字,也能显示自定义View。我们用一个简单的案例来演示UIPickerView的基本使用方法,需求是实现滚动选择数据,并将选中的数据赋值给指定的控件,并提供一个随机选择的方法。最终效果图如下所示:

035-多控制器管理(1)-iOS笔记

首先我们直接在Main.storyboard中搭建界面,由于只是演示,我就只做了UIPickerView的适配。

035-多控制器管理(1)-iOS笔记

我们将选择器中所要展示的数据存储在plist文件中了,并且没有用到字典,所以无需封装模型直接先懒加载数据存储到一个数组中即可。

035-多控制器管理(1)-iOS笔记

ViewController.m

 三、UIPickerView显示自定义View

用一个国旗选择的案例来演示如何让UIPickerView显示的数据是自定义View而不是纯字符串,其实和上面的案例区别不大,只是换了一个返回每列、每行数据如何显示的代理方法。上面案例是直接返回字符串,这里我们需要返回一个自定义View而已。下图是我们的需求:

035-多控制器管理(1)-iOS笔记

首先创建项目导入plist文件,数据是以字典形式存储的,所以我们需要封装模型。

035-多控制器管理(1)-iOS笔记

JFFlag.h

 JFFlag.m

在Main.storyboard中搭建界面,这里我们只需要拖拽一个UIPickerView控件即可。

035-多控制器管理(1)-iOS笔记

UIPickerView显示的自定义View,也就是类似于我们之前学过的UITableViewCell。这里我们也单独封装自定义View,并用xib来描述这个View,并进行属性连线。

035-多控制器管理(1)-iOS笔记

然后实现封装类中的方法,提供一个快速创建自定义View的类方法和为自定义View的子控件赋值的方法。

JFFlagView.h

 JFFlagView.m

最后我们在控制器中懒加载数据,并实现UIPickerView的数据源和代理方法,进行数据的展示。

ViewController.m

 注意:在iOS6之后,返回的View就不能重用了,因为苹果觉得UIPickerView展示的数据量都非常小,没有必须重用。如果是在iOS6之前,也可以重用View。

四、UIDatePicker

UIDatePicker是一个日期选择器控件,他的用法和UIPickerView类似。UIDatePicker继承自UIControl,所以可以添加监听事件。但是有些童鞋认为UIDatePicker是UIPickerView的子类,事实不是这样的,只是在UIDatePicker内部封装了一个UIPickerView,所以不要弄错了啊。并且UIDatePicker控件经常和UIToolBar一起使用,也就是给日期选择器添加一个工具条。

 五、UIPickerView基本使用方法

使用UIDatePicker和UIPickerView完成选择生日和省份的功能,自定义键盘其实就是为UITextField的inputView赋值一个自定义View,工具条则是为UITextField的inputAccessoryView赋值一个自定义的View。

自定义UITextField弹出的键盘:

这里第一个文本框的inputView赋值一个UIDatePicker,inputAccessoryView则是一个UIToolBar。

第二个文本框的inputView赋值一个UIPickerView,inputAccessoryView也是一个UIToolBar。

035-多控制器管理(1)-iOS笔记

创建项目,在storyboard中搭建界面,这里只需要拖拽两个UILabel和UITextField即可,其他控件需要代码创建 。

035-多控制器管理(1)-iOS笔记

搭建好界面先来创建模型,导入plist文件观察可轻易发现数据的结构。每一个字典中有两个键值对,一个是城市数组,另一个是省份字符串。由此可以确定,UIPickerView的第一列显示的数据就是所有省份,第二列显示的数据则是每个省份对应的城市,而不是固定的数据。

035-多控制器管理(1)-iOS笔记

字典转模型,返回模型数组。已经写了无数遍了,就不再解释了。提供一个返回模型数组的类方法,方便懒加载时直接调用这个类方法返回模型数组。

Province.h

Province.m

封装好模型后,在控制器中懒加载模型数组。并完成其他一系列调用,具体代码如下:

ViewController.m

六、项目中的常见文件

Info.plist是整个项目的重要配置文件不能删除。

Localization native development region :本地化相关。

Bundle display name :程序安装后显示在iphone/ipad上的名字。

Icon file :程序的图标,Xcode5以前创建的项目有,一般用Icon.png,Xcode5以后创建的不在plist设置,在Images.xcassets设置。

Bundle version :程序版本号,AppStore每更新版本,版本要增加,内部项目管理的版本号,不对外。

Bundle versions string, short :用于itunes上显示的版本号,即对外的版本。一般3个数组成。

Bundle identifier :应用的惟一标识,发布到AppStore去。

pch文件干什么用?

pch文件里的内容被项目中的其它所有资源共享访问,定义宏 身高、电话和其它文件共享使用、自定义日志输出。我们在开发阶段,在pch中使用DEBUG模式自定义日志输出宏,当app发布后这些宏就失效。

因为pch中的内容会呗项目中其它所有资源共享访问,所以有可能我们项目中不只是有oc文件,还会有其它语言文件。所以我们在定义被共享的内容时,应该加判断。

注意:一般公用的资源写在#ifdef __OBJC__里面。

七、App启动原理

UIApplication

什么是UIApplication?

1.UIApplication是整个应用程序的象征,就像中国的象征是五星红旗。

2.每一个应用都有自己的UIApplication,而且是单例,通过[UIApplication sharedApplication]获取。单例对象也就是程序运行到结束,只能有一个对象。如果我们使用[[UIApplication alloc] init]创建对象,程序不被允许并且会直接报错,因为application只有能一个对象。

3.ios程序启动后创建的第一人对象就是UIApplication对象。

UIApplication用来用来设置全局性的东西

设置网络请求状态/取消网络请求状态

设置应用图标数字/清除图标数据

不过在iOS8更新后不能直接这样设置应用图标的数字了,需要先获得用户的授权,才能显示。完成代码如下:

设置状态栏样式

方式1.由控制器的一个方法决定

方式2.使用application设置

但是这样设置默认是不起作用的,因为默认状态栏样由控制器来管理,如果想用application设置状态栏有效,得在Info.plist的设置View controller-based status bar appearance = NO

打电话、发短信、发邮件、打开网站

调用application的openURL方法即可,这里就只演示打开网站,其他同理。

UIWindow

什么是UIWindow?

1.UIWindow是用来显示控制器的View的。

2.每一个应用程序都有一个窗口。

演示UIWindow,在没有设置主要storyboard的情况下

首先在info.plist文件中清空Main storyboard file base name的value。

035-多控制器管理(1)-iOS笔记
在AppDelegate.m文件中的didFinishLaunchingWithOptions方法中创建窗口,设置为主窗口并可见。

效果如下:

035-多控制器管理(1)-iOS笔记

窗口是一个特殊的UIView对象,可以往window添加子控件,如label、switch等等。但是一般不会在窗口添加子控件,会设置窗口的rootViewController属性,将控制器的view添加到窗口上。

注意:如果直接把控制器的view添加到窗口是不能让控制的view进行旋转的,但设置窗口的根控制器,控制器的view可以旋转。因为旋转事件传递是由UIApplication -> UIWindow -> 根控制器,窗口不会做旋转处理,只有控制器才会。所以别直接将UIView添加到UIWindow上面

获取主窗口方式

一个窗口当前能接受键盘和非触摸事件时,便被认为是主窗口。还有下面三种方式都能获取主窗口:

上面的情况是在info.plist中没有指定主要的storyboard,才需要手动创建UIWindow,并创建控制器赋值给UIWindows的rootViewController属性,再设置UIWindow为主窗口并显示。

还有一种情况就是在已经在info.plist中指定了主要的storyboard,这样程序会自动创建窗口,设置窗口的根控制器为storyboard的控制器,让窗口成为主窗口并显示。

App启动原理

我们从第一天开始学习C语言就知道,程序是入口是main函数,OC也不例外!所以程序运行首先执行main函数,main函数就一行代码,不过这一行代码可做了不少事情,main函数如下:

1.程序运行后根据main函数中第三个参数创建UIApplication对象,UIApplication是程序中创建的第一个对象。这个参数如果为nil默认就是UIApplication,如果换成我们自己创建的类,就必须继承自UIApplication。

2.根据main函数中第四个参数创建UIApplication的代理对象,并赋值给UIApplication对象的delegate属性,并开启Main Runloop(事件循环)。

3.进行事件的处理,首先会在程序启动完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法。此时要分两种情况进行处理了,首先会去info.plist文件中查找是否设置了主要的storyboard文件名。

如果没有设置storyboard:我们需要手动在AppDelegate.m中的application:didFinishLaunchingWithOptions:中创建UIWindow,然后创建和设置UIWindow的rootViewController。最后设置UIWindow为主窗口并可见。

已经设置storyboard:根据Info.plist获得最主要storyboard的文件名,加载最主要的storyboard。自动创建UIWindow,自动创建和设置UIWindow的rootViewController为当前storyboard的控制器(再次提醒:这一步其实是将rootViewController中控制器的view添加到窗口上显示)。最后设置UIWindow为主窗口并可见。

六阿哥

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: