工程管理
从源码到APP
源代码文件(.m或.h)通过编译生成目标文件(.o),再通过连接生成可执行文件(mach-o或.dylib),可执行文件与处理过的资源文件(.plist或.png或.storyboard文件处理转化为二进制文件)再经过打包最终生成发行包(.app或.framework文件)
Xcode工程涉及的概念
Workspace
Workspace用来管理一组Project(项目),将其所管理的项目放在同一个文件夹下,用于保存项目状态,保存构造出来的产品,同时在同一个Workspace中的项目可以互相引用(implicit dependency)。Xcode会自动为独立的项目提供Workspace(隐藏形式的)。加入到Workspace里的项目仍可独立打开,注意如果项目中使用了Workspace里其他项目的资源就只能在Workspace中打开了。
Project
Project用来定义工程需要用到的哪些文件,所需文件必须加载到Project中才可以访问。管理构建Target(目标),告诉Xcode当前用到了哪些构建和执行目标。
Target
定义如何构造一个产品,指定用到的文件子集,定义依赖关系,提供构建过程的规则与参数。在Build Phases
的Complie Source选项下可以看见参与编译的所需文件。
Scheme与Destination
行动方案(Scheme)是一组指令,在指定目标上完成特定任务。Destination用来选择使用哪种模拟器来生成代码。
库与框架
staic library(.a)静态库:配合响应的头文件我们就可以直接使用了,程序运行时将会全部加载到内存中。
dynamic library(.dylib)动态库:当程序运行时没有和静态库一样加载到内存里面,而是在需要使用时再自动加载到内存中使用的库文件。
framework(.framework)框架:一个按照特定格式包装起来的动态库。
CocoaPods
CocoaPods是一个第三方的模块管理工具,它可以帮我们自动解决第三方库版本更新的问题。安装CocoaPods有三个步骤:
1.安装
$ sudo gem install cocoapods
$ pod init
2.定义
在项目根目录下编写Podfile
platform:ios,'8.0 '
use_frameworks!
pod'AFNetworking','->2.0'
3.使用
$ pod install --no-repo-update
iOS界面解析
UIScreen:用来表示设备目前可以使用的屏幕,在默认情况下是在mainScreen(设备自带的屏幕)屏幕上显示,也有时在externalScreen(外接显示屏幕)上显示。
+mainScreen 拿到主屏幕的实例。
如果外接了其他屏幕
+screens 拿到所有屏幕的实例
(BOOL).mirroredScreen 判断主屏幕和外接屏幕是否为镜像显示
.currentMode 屏幕的显示模式,记录了屏幕的大小,和纵横比
.overscanCompensation 匹配各种不同分辨率的屏幕,多用于外接电视
.bounds 这个函数平时使用较多,主要在我们想创建一个View时用于获取屏幕的大小。
.applicationFrame 获取屏幕可见的区域,是bounds减去状态栏的区域。目前已经过时,仅在维护老代码的时候使用。
.scale 罗辑上的像素点和实际硬件屏幕的像素点的差别,假设罗辑像素的大小是100乘200,如果scale是2的话物理屏幕的大小是200乘400。
- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 获取一个屏幕的截图返回一个UIView。
UIWindow
WIndow代表当前应用可用的屏幕区域。
.windowLevel属性表示窗口所在的层级,层级越高显示的越在前面。
.windowLevel >= UIWindowLeveStatusBar 这样设置Window将会挡在StatusBar之前。
UIView的层次管理方法
增:
-(void)addSubview:(UIView *)view 增加一个子view
-(void)insertSubview:(UIView *) atIndex:(NSInteger) 在atIndex处插入一个子view
-(void)insertSubview:(UIView *) belowSubview:(UIView *) 在一个子view之后插入一个子view
-(void)insertSubview:(UIView *) aboveSubview:(UIView *) 在一个子view之前插入一个子view
删:
-(void)removeFromSuperview 将一个view从父view中删除
改:
-(void)bringSubviewToFront:(UIView *)view 将子view调到前面来
-(void)sendSubviewToBack:(UIView *)view 将子view调到后面去
-(void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2
将位置在index1和index2的两个子view位置互换
查:
.window 表示当前view所在window
.superview 表示当前view所在的父view
.subviews 表示当前view所有的子view
-(BOOL)isDescendantOfView:(UIView *) 判断一个view是否是当前view的上级关系
UIView: 表示屏幕上一块矩形区域:负责提供相应区域的显示内容,也处理相因区域的事件响应。
-resizeToFit 让UIView自动调整大小,让其所有的子view可以显示出来。
opaque 一个bool属性,no时表示为不透明。
maskView 一个view可以设置maskView属性,生成一个View的模板,如果不透明的就裁剪,半透明的就混合
.tag 每一个view都可以设置一个tag(一个整数),用来区分之间的区别。
UIAppearance
修改某类多有实例的外观
在View加入Windows时生效
不影响已经显示的View(需要移出再加回)
事件处理
UIResponder
定义事件响应组件的接口
提供基础实现
Responding to Touch Events
touchesBegan:withEvent:
touchesMoved:withEvent:
touchesEnded:withEvent:
touchesCancelled:withEvent:
touchesEstimatePropertiesUpdated:
Responding to Motion Events
motionBegan:withEvent:
motionEnded:withEvent:
motionCancelled:withEvent:
Responding to Press Events
pressesBegan:withEvent:
pressesCancelled:withEvent:
pressesChanged:withEvent:
pressesEnded:withEvent:
Responding to Remote-Control Events
remoteControlReceivedWithEvent:
Responder Chain
响应会串成一个链条
.nextResponder指向了下一个响应
.isFirstResponder来表明是否为第一个响应
Hit-Test找到最可能响应触摸事件的View
通过-[UIView hitTest:(CGPoint)withEvent:(UIEvent *)]
-[UIView pointInside:withEvent:]
方法可以确定点击的位置(坐标)。
递归询问每个pointInside为YES的subview,如果pointInside为NO的subview子树整个略过,如果clipsToBounds = NO,在subview超出superview的地方的点击事件将不会响应。
在自定义类里响应触摸事件
-(void)touchBegan:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchMoved:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchEnded:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
UITouch
-previousLocationView: 上一下次触摸事件的位置
-locationInView:
.timestamp 按下的时间
.type 是手指按下还是触摸笔按下
.force 按下的力度感应
UIEvent
.type:UIEventTypeTouches(Motion/RemoteControl/Presses)
.timestamp
手势操作
目前在iOS编程中手势的识别主要是靠UIGestureRecognizer来识别
创建一个手势识别器
-initWithTarget:(UIView *) action:(SEL)handleGesture
将创建的手势识别器加到一个View上
-[UIView addGestureRecognizer:]
手势识别器针对不同的手势有不同的类型
UITapGestureRecognizer 识别点击动作
UITapPinchRecognizer 识别两个手指向内滑动动作
UIPanGestureRecognizer 识别拖动动作
UISwipeGestureRecognizer 识别滑动动作
UIRotationGestureRecognizer 识别旋转动作
UILongPressGestureRecognizer 识别长按动作
同时支持多种手势
用依赖关系改变触发顺序
-[a requireGestureRecognizerToFail:b]
b失败前,a先候着
使用UIGestureRecognizerDelegate控制
-gestureRecognizer:shouldReceiveTouch:
这个touch要不要处理
-gestureRecognizerShouldBegin:
这个识别可以开始了吗?
-gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
识别器可以一起触发吗?
UIScrollView
UIScrollView是一个能Scroll的UIview
创建ScrollView
在interface里拖
代码创建
scrollView = [[UIScrollView alloc] initWithFrame:rect];
ScrollView的尺寸
ScrollView的滚动
要实现滚动,scrollEnabled属性要设置成YES
监听滚动情况
scrollView.delegate
UIScrollViewDelegate
-scrollViewWillBeginDragging:(UIScrollView *); 确认用户已经开始拖动了
-scrollViewDidScroll:(UIScrollView *); 用户在拖动的过程中
-scrollViewDidEndDragging:(UIScrollView *) willDecelerate:(BOOL); 用户已经完成拖动动作
Pinch响应
UIScrollViewDelegate
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)
-scrollViewDidEndZooming:withView:atScale:
.minimumZoomScale
.maxmumZoomScale
UIScrollView
-setZoomScale:(CGFloat)animated:(BOOL)
-zoomToRect:(CGRect)animated:(BOOL)
直接zoom是位图缩放而非重绘,要用CATiledLayer实现平滑缩放
分页滚动