一.控件
1.属性
1> frame和bounds的区别
frame:可表示尺寸和位置,与父视图坐标系的关系,位置以自己的左上角为原点,可用于形变和位移
bounds:可表示尺寸和位置,与自身视图坐标系的关系,大多数情况(滚动视图的子视图等除外)以自己的中心点为原点,可用于形变
center:只表示位置,表示自己中心的坐标,可用于位移
2>?trasform
修改位移\形变\旋转,transform不同于board\center\frame,前者中记录的是形变的数据,不发生形变其值是空的,所以我们需要新建结构体,用CGAffineTransform(仿射变换)函数给对象结构体属性赋值,而后者是控件的固有属性,内存数据是始终存在的,当我们用他们做移动等操作时,是改变其值,所以是结构体赋值三步曲,不用CG的函数
使用情景区别: transform一般用于有来有回的变化,而frame是有去无回
2.UITableview
1> 自定义高度
1.1>新建一个继承自UITableViewCell的类
1.2>重写initWithStyle:reuseIdentifier:方法
1.3>添加所有需要显示的子控件(不需要设置子控件的数据和frame,??子控件要添加到contentView中)
1.4>进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)
1.5>提供2个模型
数据模型: 存放文字数据\图片数据
frame模型: 存放数据模型\所有子控件的frame\cell的高度
1.6>cell拥有一个frame模型(不要直接拥有数据模型)
1.7>重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame
3.UICollectionView
1> 如何实现瀑布流,流水布局
通过实现UICollectionViewDelegateFlowLayout去改变单元格大小
2> 和UITableView的使用区别
1)必须使用下面的方法进行Cell类的注册:
- (void)registerClass:forCellWithReuseIdentifier:
- (void)registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
- (void)registerNib:forCellWithReuseIdentifier:
2)collectionView与tableView最大的不同点,collectionView必须要使用自己的layout(UICollectionViewLayout)
如:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(52, 52);???????????????// cell大小
flowLayout.minimumInteritemSpacing = 1;?????????????????// cell间距
flowLayout.minimumLineSpacing = 1;????????????????????? // cell行距
flowLayout.sectionInset = (UIEdgeInsets){81,1,1,1};?????// cell边距
创建collectionView需要带Layout的初始化方法:
- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
二.生命周期
1> 应用的生命周期
各个程序运行状态时代理的回调:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions??告诉代理进程启动但还没进入状态保存
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions?? 告诉代理启动基本完成程序准备开始运行
- (void)applicationWillResignActive:(UIApplication *)application?? 当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了
- (void)applicationDidBecomeActive:(UIApplication *)application??? 当应用程序入活动状态执行,这个刚好跟上面那个方法相反
- (void)applicationDidEnterBackground:(UIApplication *)application?? 当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可
- (void)applicationWillEnterForeground:(UIApplication *)application?? 当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。
- (void)applicationWillTerminate:(UIApplication *)application?? 当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。
#warning 添加图片
2> 视图的生命周期
loadView - 默认调用super方法,根据控制器创建方式加载视图,重写后将根据重写方法创建视图
viewDidLoad-视图加载完成
viewWillAppear-UIViewController对象的视图即将加入窗口时调用;
viewDidApper-UIViewController对象的视图已经加入到窗口时调用;
viewWillDisappear-UIViewController对象的视图即将消失、被覆盖或是隐藏时调用;
viewDidDisappear-UIViewController对象的视图已经消失、被覆盖或是隐藏时调用;
viewVillUnload-当内存过低时,需要释放一些不需要使用的视图时,即将释放时调用;
viewDidUnload-当内存过低,释放一些不需要的视图时调用。
3>??load?initialize方法的区别
+(void)load
+(void)initialize
执行时机
在程序运行后立即执行
在类的方法第一次被调时执行
若自身未定义,是否沿用父类的方法?
否
是
类别中的定义
全都执行,但后于类中的方法
覆盖类中的方法,只执行一个
4> 创建控制器、视图的方式
4.1> 创建控制器的方式
1)通过代码的方式加载viewController
UIViewController *controller = [[UIViewController alloc] init];
2)通过stroyboard来加载viewController
2.1) 加载storyboard中箭头指向的viewController
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; //加载箭头指向的viewController
CZViewController *controller = [storyboard instantiateInitialViewController];
2.2) 加载storyboard中特定标示的viewController(storyboard可以有多个controller)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
CZViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"two"];
3)通过xib加载viewController
3.1) 传统方法
3.1.1)创建Xib,并指定xib的files owner为自定义控制器类(为了能连线关联管理IB的内容)
3.1.2)xib中要有内容,且xib中描述的控制器类的view属性要与xib的view控件完成关联(关联方法两种,一种是control+files owner拖线到xib中搭建的指定view控件,另一种是指定xib中的view拖线到@interface)
3.1.3)从xib加载viewController
CZViewController *controller = [[CZViewController alloc] initWithNibName:@"CZOneView" bundle:nil];
3.2)bundle中取出xib内容
CZViewController *vc = [[NSBundle mainBundle] loadNibNamed:@"Two" owner:nil options:nil].lastObject;
4.2> 创建视图的方式
1.用系统的loadView方法创建控制器的视图
2.如果指定加载某个storyboard文件做控制器的视图,就会加载storyboard里面的描述去创建view
3.如果指定读取某个xib文件做控制器的视图,就根据指定的xib文件去加载创建
4.如果有xib文件名和控制器的类名前缀(也就是去掉controller)的名字一样的?? xib文件 就会用这个xib文件来创建控件器的视图 例:控件器的名为 MJViewController??xib文件名为 MJView.xib?? 如果xib文件名后有一个字不一样就不会去根据它去创建如:MJView8.xib
5.找和控制器同名的xib文件去创建
6.如果以上都没有就创建一个空的控制器的视图;
三.多控制器管理
1.
四.核心绘图
6> View和layer的区别
图层不会直接渲染到屏幕上,UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器。一个UIView上可以有n个CALayer,每个layer显示一种东西,增强UIView的展现能力。
6.1>都可以显示屏幕效果
6.2> 如果需要用户交互就要用UIVIew,其可接收触摸事件(继承UIResponder),而CALayer不能接收触摸事件
6.3> 如果没有用户交互可选用CALayer,因为其所在库较小,占用的资源较少
7> new和alloc init的区别
采用new的方式只能采用默认的init方法完成初始化,采用alloc的方式可以用其他定制的初始化方法。
五.核心动画
六.事件处理
1> 描述响应者链条
当触摸事件发生时,压力转为电信号,iOS系统将产生UIEvent对象,记录事件产生的时间和类型,然后系统将事件加入到一个由UIApplication管理的事件队列中。
UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)
主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件(从父到子,从后到前),这也是整个事件处理过程的第一步
找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理
4.Runloop
1> 每个线程上都有一个runloop,主线程默认开启,辅助线程需要手动开启,主要用于
使用端口或自定义输入源来和其他线程通信
使用线程的定时器
Cocoa中使用任何performSelector…的方法
使线程周期性工作
七.iOS适配:
1、屏幕适配:a.storyboard&XIB自动布局;b.纯代码:(1)计算frame;(2)Masonry框架——OC:Autolayout库;swift:SnapKit库
2、方法适配:根据不同的iOS版本选择不同的方法。