在main文件中,UIApplicationMain函数一共做了三件事
- 根据第三个参数创建了一个应用程序对象
- 默认写nil,即创建的是UIApplication类型的对象,此对象看成是整个应用程序的一个抽象,负责存储应用程序的状态。
- 根据第四个参数创建了一个应用程序代理类对象
- 所谓代理,及帮助另一个对象做事情。上面第一步中创建的应用程序对象只负责存储应用程序的状态,但不提供响应,而是给代理发消息,由代理负责针对不同的状态提供响应。比如说:程序一启动,代理就要响应一下,说明弹出的第一个界面是谁。
- 其中,就是传入一个类的类名字符串即可,此代理类对象一定是系统创建的,而且只有一个,也就是单利。其中AppDelegate class返回的是这个类的类型描述信息,在使用NSStrinFromClass这个函数,从类型信息中把类名以名字符串形式返回。
- 第三件事,启动了事件循环
- 一个背后运行的死循环,用于不停地检测屏幕上的触点事件,一检测到触摸事件,立即将此事件传给用用程序,让程序提供相应
如何搭建一个界面? - UIViewController
- 作用:
- 负责创建界面
- 负责提供界面与用户的交互响应
- 特点:
- 天生自带一个视图属性,所有界面设计就是添加到这个视图即可。
- 规范写法:
- step1:创建一个类,继承自UIViewController
- step2:在类中的viewDidLoad方法方法中,编写构建界面的代码
- step3:在启动方法中,只需要将这个自定义的类创建出实例,作为window的根视图控制器即可
- viewDidLoad方法的特点:
- 此方法是控制器的那个view生命周期的起始点,即创建完view实例之后,第一个执行的方法,并且此方法只会调用一次
- 除此方法外,view还会存在其他状态,如:viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear,这些方法会随着view的显示或隐藏而执行多次,但只要控制器没有销毁,view没有销毁过,则viewDidLoad方法只会调用一次
界面元素的基础 - UIView
- 是什么?所有界面上看的见的东西都是UIView的子类,系统定义的一个通用的描述界面上某个可显示的矩形区域,一个重要的特性就是具备容器性,即UIView可以内部添加其它的UIView,除此以外它还能提供触点的响应。
- 核心属性:
- frame(框架,边框):用于描述这个视图在父视图中的位置及占据的区域大小
- CGRect结构提类型
- 包含origin属性和size属性
- origin:CGPoint类型的结构体
- size:CGSize类型的结构体
- CGRect包含四个浮点,两个存储x和y用于定位,两个存储width和height用于描述大小
- CGRect结构提类型
- 如何构建一个CGRect类型的结构体变量呢?
-
使用一组函数即可,函数名规律是是:结构体类型名 + Make
CGRect -> CGRectMake(x,y,w,h);
CGPoint -> CGPointMake(x,y);CGSize -> CGSizeMake(w,h);UIEdgeInset -> UIEdgeInsetMake();特殊:UIRange -> UIMakeRange()
-
- frame(框架,边框):用于描述这个视图在父视图中的位置及占据的区域大小
- 有哪些子类?
- UIWindow、UILabel都是UIView的直接子类,有一个特殊的分支叫UIControl,特殊之处在于有自己的高级事件,也管这个分支叫控件,UIButton、UITextField都是控件,但UILabel不是空间,虽然口头交流时经常误把很多不是空间的视图也称之为控件,但概念要清楚,只有UIControl的子类才能叫做控件。
UIView的几个子类:
- UILabel 标签
- 作用:显示文字
-
核心属性:
text
: 类型NSStringnumberOflines
:显示的行数,默认是1,如果设置为0,则代表行数无上限font
:字体,字号textColor
:文字颜色backgroundColor
:背景色textAlignment
:水平方向文本的对齐方式
- UIButton 按钮
- 作用:以文字或图片的样式提供给用户一个可点击并相应的区域
- 核心属性:默认图文左右排
- 文字title:
setTitle: forState:
- 图片image:
setImage: forState
对于后缀是.png的图片省略后缀,其他的图片类型就需要加后缀名。 - 背景图backgroundImage:
setBackgroundImage: forState
- 按钮有四个状态:normal(摆在那不动)、highlight(高亮状态,按下去不松手)、selected(选中状态,通过设置按钮的selected属性为YES才会进入到这个状态)、disable状态(不能用状态,通过设置按钮的enable属性为NO时进入此状态)
- 文字title:
- 创建事项:
- 使用工厂方法创建按钮式,可以通过参数指定是系统版还是自定义版
- 使用new或alloc init 方式创建的按钮,等价于传自定义版参数
- 如何选择使用系统版,还是自定义版按钮呢?
- 因为系统自带高亮,所有美工给一套图时,就选系统版
- 如果美工给了两套图,就选择则自定义版
- 自定义扮,title的文字颜色为白色,系统板时有默认颜色,title为蓝色
- 核心事件:
- 事件种类:
touchUpInside
- 如何添加对事件的响应:
addTarget: action: forControlEvent
- 事件种类:
- UITextField
- 作用:接受输入
-
核心属性:
text属性:NSString类型。可读可写,读取就是获取输入的文字,给属性赋值,则文字会显示到文本框中
键盘属性设置边框样式:borderStyle
设置键盘样式:keyboardType
设置键盘右下角按键的样式:returnType
设置键盘整体色系风格:keyboardAppearance
设置键盘是否是密码框:secureTextEnter
-
核心事件:
插播知识点
[xxx copy]
将长度可变的的复制成长度不可变的
[xxx mutableCopy]
将长度不可变的复制成长度可变的NSArray --> [NSArray NSmutableCopy] -->NSmutableArray
问题
字符串类型的属性是用什么修饰?
答案:使用copy修饰,因为有一种特殊情况,就是一旦将MutableString赋值给属性,一旦有其他的引用也指向这个可变字符串,就会有修改其内容的可能。这样的话,就会导致明明声明的是不可变长度的属性,会发生内容的改变。一旦用了copy修饰,则就算赋值一个可变长度的内容,也会先执行一次copy,将其拷贝成一份长度不可变的副本,让属性只想这个副本,就算有其他引用修改那个长度可变的字符串,也不会影响副本的内容。---
- 文本框
- 键盘为什么弹起来?
- 当有触点在文本框时,系统对这个触摸动作进行了响应,相应的结果就是让文本框成为第一响应者
[textField becomeFirstResponder
成为第一响应者 ,调用键盘
- 如何收键盘?
- 取消掉文本框的第一响应者身份即可
[textField resignFirstResponder]
- 什么时候收键盘?
- 情况一:点击屏幕的空白处:点击控制器的那个view
- 实现控制器的
touchesBegan:
方法即可
- 实现控制器的
- 如果有多个键盘:如果界面中有多个文本框,那么可以通过结束他们父视图的编辑状态方法
- 批量关闭所有文本框弹起的键盘:
[self.view endEditing:YES];
- 批量关闭所有文本框弹起的键盘:
- 情况二: 点击键盘右下角return按键
- (BOOL)textFieldShouldReturn:(UITextField *)textField
- 右下角按键类型:
returnKeyType
- 情况一:点击屏幕的空白处:点击控制器的那个view
- 密码框:
secure
- 提示性:
placeHolder
- 键盘为什么弹起来?
- 代理
- 遵守协议
- 实现协议中的方法
- 设置委托方的代理人为当前对象
- 代理方法的第一个参数,是委托方本身。
- 懒加载
- 也叫延迟加载,等到需要使用时才开辟空间创建对象
- 消息框UIAlertContent
- 作用:弹出提示,有两种样式,屏幕中间,屏幕底部
- 如何解决样式?创建实例的时候,通过style参数,alert样式在屏幕中间,actionsheet在屏幕底部
addTextFieldWithConfigurationHandler:
参数是 block ,在block中可以设置 alert帮我们创建 文本框- 数组中的 文本框 是 第四步 添加进来的文本框UITextField usernameField = alert.textFields[0];UITextField passwordField = alert.textFields[1];
- 使用xib技术实现界面
- 理念:将控制器中原本需要些大量代码进行构建界面的过程,通过一个后缀是xib的文件简化此操作。当再去创建控制器实例时,系统会通过读取xib文件,完成界面的创建。针对系统创建的这个视图,需要在控制器中访问时,可以通过连线的方式完成关联。
- IBOutlet关键字:将控制器中的属性与界面中系统创建的某个视图关联在一起
- IBAction关键字:键控制器中的方法与界面中系统创建的某个视图的时间关联在一起
- 切换VC
- A -> B:使用的是A控制器的presentViewController方法
- B -> A:使用的是B控制器的dismissViewController方法
注意A和B的声明周期
:A推出B时,虽然看不见A了,但是A没有被摧毁,从B返回A时,B会被销毁,A从隐藏状态编程显示状态
- 使用xib简化创建界面的过程
- 如何实现
- 借助于系统的Interface Builder 完成,IB以前是一款独立的软件,现在整合到xcode中, 只需要创建自定义的控制器时,勾选下面的“Also Creat Xib file”选项,则自动生成与控制器名相同,后缀为xib的文件,xib以前叫做叫nib
- UIStepper 步进控件
- 作用:记录一个浮点值,并且控件提供了两个按键界面,由用户精确地控制记录支个值得递增或递减
- 核心属性:
value
- 核心事件:
valueChanged
- UISlider 滑块控件
- 作用:记录一个浮点值,通过一个可以滑动的按键,快速在某个范围内得到一个不容易精确控制的数值
- 核心属性:
value
- 核心事件:
valueChanged
- UISwitch 开关控件
- 作用:记录一个布尔值,通过点击的方式,可以记录用户是否的选择
- 核心属性:
on(BOOL类型)
- 核心事件:
valueChanged
- SegmentedControl 分段控件
- 核心属性:
selectedSegmentIndex
- 核心事件:
valueChanged
- 核心属性:
- Activity Indicator 菊花控件
- 核心属性:
isAnimating
- 核心方法:
startAnimating
stopAnimating
- 核心属性:
- Progress 进度提示条
- 核心属性:
progress
(0 ~ 1 浮点)
- 核心属性:
注意:浮点型和整形相比,永远也到不了1。浮点型精确到小数点后6位
- NSTimer定时器
- 作用:可以设置某方法,每个一段时间,自动执行
- 如何创建并启动?
- timerXXXXX : 创建好的定时器,不会自动启动,我们只有把该定时器添加到事件循环中
- scheduleXXXX: 创建好定时器后,自动启动
- DatePicker
- 核心属性:
date
- 核心方法:日期格式化
HH - mm - ss yyyy - MM - dd
- 核心属性:
- PickView
- 我们关注三问一答
- 三问:(DataSource)
- 有多少列
- 每列有多少行
- 每行长什么样子
- 一答:(delegate)
- 选中某行如何处理
- 三问:(DataSource)
- 我们关注三问一答
- UINavigationController导航控制器
- 作用:为了管理多个控制器
- 配置导航类(NavigationBar)
- 高度:算上状态栏64个点(状态栏20个点)
- 内容:通过navigationItem属性来完成设置
navigationItem设置的是每个界面上导航栏中的内容
- 左:
leftBarButtonItem
/leftBarButtonItems
- 中:
title
/title View
- 右:
rightBarButtonItem
/rightBarButtonItems
- 左右都是类似于可点击的按键,是UIBarButtonItem类型
- 如果修改
NavigationBar
的外观,该导航下所有子控制器都会改变self.navigationController.navigationBar.tintColor = [UIColor redColor];
- 配置工具栏(toolBar)
- 位于导航界面的底部,默认是隐藏的,高度44个点,通过设置
Navigation.toolBarHidden = NO
即可显示 - toolBar中可以通过toolBarItem的属性,设置按键,位置不分左中右,可以用木棍,弹簧调整视图。
- 位于导航界面的底部,默认是隐藏的,高度44个点,通过设置
- 设置导航控制器的titleColor
- UIImageView
- UIImage(存图片) -> UIImageView(显示图片的视图)
- 核心:image
UIViewContentModeScaleToFill 默认,设置的宽高是多少,就是多少
UIViewContentModeScaleAspectFit 保持宽高比
UIViewContentModeScaleAspectFill 保证宽高比,可能图片会被切割掉
- //裁剪 姿势图超出的部分iV.clipsToBounds = YES;
- UIKit层面动画
- 预备:动画 -- 序列帧动画
- 每一帧是一张静态的图片,按照一定间隔时间,快速连续播放,最终通过人眼的视觉停留效果实现的动画
- 预备:动画 -- 序列帧动画
- UIScrollView滚动视图
- 作用:用于查看更大范围的图片或文字内容信息的视图
- 特点:虽然是视图,但本身scrollView没有外观,主要是通过加载子视图来完成的展示,内部子视图的区域可以大于scrollView占据的空间,通过滑动这种交互方式能够实现查看超出范围的那些子视图
-
核心属性:
frame
可视区域的大小contentSize
内容大小(可以滑动区域的大小)contentOffset
记录滑动的偏移量pagingEnabled
设置整页滑动showsHorizontalScrollIndicator
是否隐藏水平滚动条showsVerticalScrollIndicator
是否隐藏竖直滚动条bounces
是否有弹性效果
- UIPageControl
- 作用:页数的提醒
- 外观:一条区域中包含多个小圆点
- 核心属性:
numberOfPages
圆点的个数currentPage
当前被选中的是第几个小圆点(下标从0开始)pageIndicatorTintColor
设置未选中的圆点颜色currentPageIndicatorTintColor
选中圆点的颜色userInteractionEnabled
是否与用户交互
- 与ScrollView配合页数移动方法:
- 在scrollView的协议方法中
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ NSInteger currentPage = scrollView.contentOffset.x / scrollView.frame.size.width + 0.5; self.pageControl.currentPage = currentPage; }
- UITableView表示图
- 作用:实现以一列多行来显示大量数据的一种视图,父类是ScrollView
- 表格样式
- 普通样式:
plain
- 分区样式:
group
- 普通样式:
- 表示图的样式
- 表示图的使用
- 创建实例
- 设置frame
- 添加到父视图中
- 设置数据源方法 三问
- 设置代理 一答
- UITableViewController表示图控制器
- 特点:
- 继承自UIViewController,天生自带一个UITableVIew属性,通过tableView属性访问即可,此表示图的dataSource和delegate代理已经被设置为当前的表示图控制器,并且表示图控制器也已经遵守了UITableView和UITableViewDelegate协议
- 使用:
- 在使用上,在创建一个类继承UITableViewController,只需关注三问一答即可
- 特点:
- cell的复用
- 方式一:
- 原理:系统会自动将那些超出屏幕,看不见的对象回收到tableView的一个空闲队列中存储,所有在回答第三问,需要一个cell对象时,看有没有已经回收的,可以拿出来使用的cell对象,如果没有取到可重用的cell,我们就创建一个,如果取到了可重用的cell,我们就使用cell对象,但是要重新设置cell的显示内容
- 方式二:
- 原理:系统会自动将那些超出屏幕,看不见的对象回收到tableView的一个空闲队列中存储,所有在回答第三问,需要一个cell对象时,看有没有已经回收的,可以拿出来使用的cell对象,如果没有取到可重用的cell,系统会按照我们之前注册的cell帮我们创建一个cell,如果取到了可重用的cell,我们就使用cell对象,但是要重新设置cell的显示内容
- UITableViewCell的组成:
- 内容视图:
- 系统版:已经提供了三个可用的空间,用于显示文字或图片,可以通过cell的属性进行设置
cell.textLabel
cell.detailTextLabel
cell.imageView
- 样式有四款系统版:
- UITableViewCellStyleDefault
- UITableViewCellStyleValue1如果没有图片
- UITableViewCellStyleValue
- UITableViewCellStyleSubtitle
- 自定义内容视图:
- 自定义内容驶入需要通过单元格的contentView属性,找到contentView,然后往其上面添加自己的视图
cell.contentView addSubview:
视图 - 系统版:通过cell.accessoryType属性设置
- 四款:
- 自定义版
- 给cell的accessoryView复制一个自己创建的视图
cell.accessoryView = 自定义视图
- 自定义内容驶入需要通过单元格的contentView属性,找到contentView,然后往其上面添加自己的视图
- 系统版:已经提供了三个可用的空间,用于显示文字或图片,可以通过cell的属性进行设置
- 内容视图:
- 方式一:
- 表格结合各种数据模型的显示
- step1:一定要为表示图控制器增加一个属性,存储表格要显示的数据,基本上类型定为数组类型
- 前提:表格的行数是不定的,也叫动态表格
- 将数组显示到表格中:NSArray -> TableView
- 将对象数组显示到表格中
- 自定义一个数据模型类 Model(M)
self.tableView.tableFooterView
:在viewDidLoad中直接设置表尾视图self.tableView.tableHeaderView
:在viewDidLoad中直接设置表头视图self.tableView.rowHeight
:设置行高 都设置行高-
heightForRowAtIndexPath:
:设置行高的代理方法 - 向表格中添加数据
- 方式一: 全部刷新
reloadData
- 方式二: 局部刷新
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.dataArr.count - 1 inSection:0];
在使用前,一定要先将插入的数据插入到数组[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
- 方式一: 全部刷新
- 委托反向传值增加数据
-
代理传值
- 表格的编辑模式
- 什么是表格的编辑?
- 表格上提供了删除,增加,移动这样的标识,点击后可以实现表格中的数据删除,增加以及移动
- 如何进入到表格的编辑状态
- 设置表格的
editing
为YES即可
- 设置表格的
- 如何增加或删除®
- 两问一答
- 问一:当前行是否可以编辑(选问,默认是所有都能编辑)
canEditRowAtIndexPath:
- 问二:当前行是如何编辑<增加,删除>(选问,默认都是删除)
editingStyleForRowAtIndexPath:
- 答一:增加或删除编辑按键点中时应该如何处理
commitEditingStyle: forRowAtIndexPath:
- 如何移动表格中的单元格
- 一问一答
- 一问:当前行是都可以移动
- 一答:移动动作完成后如何处理后续工作
-
performSelector: withObject: afterDelay: 延迟多久调用什么方法
- 静态表格 行数固定不变
- 主要应用场景:设置界面
- 实现特点:控制器中会出现大量的硬编码,会有很多的if switch 这样的分支语句
-
下拉刷新 UIRefreshControl 的实例进行下拉刷新
- UICollectionView集合视图
- 视图可以一多行多列的形式来展示数据,是从tableView演变而来,所以在使用上,与tableView很想,从iOS6以后开始支持
- 与tableView的异同点
- 相同点:
- UITableView 关注三问一答(几个分区,每个分区多少行,每行什么样子)
- UICollectionView 关注三问一答(几个分区,每个分区多少项,每项什么样子)
- 不同点:
- UITableView
- 默认自带了用于显示数据的三个视图 textLabel,detailTextLabel,imageView
- 布局:系统定义好,永远是一列多行,从上到下,按顺序依次排列
- UICollectionView
- 不带有任何系统定义好的用于显示数据的视图,只能访问以下几个属性
backGroundColor
,backGroundView
,contentView
- 布局:需要搭配一个独立的对象来对视图中的多各项进行布局
- 布局对象:所属类型为UICollectionViewLayout或其子类,系统只给我们提供一种布局,UICollectionViewFlowLayout(流式布局)继承自UICollectionViewLayout
- 不带有任何系统定义好的用于显示数据的视图,只能访问以下几个属性
- UITableView
- UITabBarController选项卡控制器
- 以横向并列卡片式,来管理多个控制器,并已经实现了点击后的切换,和UINavigationController很想都是管理子控制器的,但不同的是导航控制器是层层推进的
- tabBarController.viewControllers = @[avc,bvc,cNavi];
- 设置当前是第几页:tabBarController.selectedIndex = 1;
- BViewController *bVC = tabBarController.viewControllers[1];
- bVC 传值;
- self.tabBarController.tabBar.tintColor = [UIColor purpleColor];
self.tabBarItem.image = [[UIImage imageNamed:@"line_bell"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
一个永远不受tintColor影响的图片
故事版
- 特点:快速开发,并可以在故事版文件了解整个应用程序的界面结构
- 启动时,系统自动做了什么?
- 根据target中配置加载Main.stroyboard文件
- 自动创建window对象
- 自动创建在故事版中有启动箭头指向的那个界面背后控制器对象
- 自动将控制器对象设置为window的rootViewController
- 自动将window显示出来
- 跳转
- 连线跳转:从一个触发跳转的控件或场景(故事版看得见界面)连线到要跳转到的目标控制器
- 连线:segue 每条线都是一个对象
- 明确跳转源头
- 明确知道跳转是哪个控件触发的,实现方式,无需写代码,直接连线
- 不明确跳转源头:
- 场景中触发跳转的控件可能是使用代码创建的,场景中条船到下一个场景的控件不明确,这些情况都是不明确跳转源头的,实现跳转的方式,选中源场景中的小黄点,连线到目标场景,选中自动生成的线,在第四个检查器中,identifier属性,为这根线起一个标识,最后在代码中,通过控制器调用
performSegueWithIdentifier
+ 线的标识,完成触发这一次跳转动作
- 场景中触发跳转的控件可能是使用代码创建的,场景中条船到下一个场景的控件不明确,这些情况都是不明确跳转源头的,实现跳转的方式,选中源场景中的小黄点,连线到目标场景,选中自动生成的线,在第四个检查器中,identifier属性,为这根线起一个标识,最后在代码中,通过控制器调用
- 跳转到故事版中一个独立的场景
- 先给独立的创景在第三个检查器中,设置storyboardID在想要跳转时利用故事版的
instantiateViewControllerWithIdentifier
方法根据storyboardID创建对应的控制器对象
- 先给独立的创景在第三个检查器中,设置storyboardID在想要跳转时利用故事版的
- 使用present或push跳转即可
- 跳转其他xib的控制器
- 跳转到其他故事版的场景中
-
传值
prepareForSegue:
使用这个方法跳转时,需要拦截下来segue对象,
找到segue对象的目标控制器segue.destinationViewController
如果目标控制器是一个导航控制器,还需要使用navi.viewControllers[0]
找到目标控制器下的跟控制器如果当前控制器有两条先,需要进行判断-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UINavigationController *navi = segue.destinationViewController; RegisterViewController *registerVC = navi.viewControllers[0]; registerVC.delegate = self; }
- viewController的属性,隐藏控制器中所有Bar:
hideBottomBaronPush
- 9 切片
- 目的:改图,使用代码的方法或直接使用xcode的功能,对一些有规律的 或 内容重复的图片进行动态的修改大小
- 通过代码实现9切片
image = [image stretchableImageWithLeftCapWidth:30 topCapHeight:30];
:这个是拉伸处理image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(20, 20, 20, 20)];
:默认是磁块平铺image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(20, 20, 20, 20) resizingMode:UIImageResizingModeTile];
-
返回值都是返回一个图片,需要用一个新的图片来接受
- 第二部分
- 绘图:(绘制图片 绘制字符串 绘制图形)
- 变形:(位移 旋转 缩放)
- UITouch
- 手势:(点击 双击 轻扫 拖拽 长按 捏合 旋转)
- 深入坐标系(frame bounds center transform)
- 动画:核心动画 CoreAnimation (CA动画)
- 布局:(代码 AutoResing AutoLayout SizeClasses)
- 通知
-
聊天页面练习
- 绘图:
-
基本概念:
图像和显示器.显示器如何显示内容?由晶体组成->发RGB的光,混合后产生不同的颜色整个显示器显示的就是一副好多个彩色的点构成的图像一个点对应就是一个像素,用4个字节保存,系统会自动将临近的4个点使用一个平均色来记录,于是图像的大小就变成了原来的1/4 - 图像内存中的图像有2种:
- 位图(点阵图)用RGB来生成(PNG,JPG)
- PNG 带透明通道,iOS开发尽量使用PNG,IPG会自动渲染回PNG
- 矢量图,保存的不是点,记录的是生成图像的公式及函数,放大,缩小时不会失真(多用于广告,海报)
- 如和绘图
- OC对象与图形的转换
- Core Graphics(核心绘图) 一套C语言的函数库
- 另外一个名字:Quart2D 苹果设备(iOS.OSX)上的2D的绘图引擎
- 为了使用方便,系统对CoreGraphice做了一些封装,直接使用UIKit下面的UIImage UIColor NSString UIBezierPath 类型也可以实现简单的曲线
- OC对象与图形的转换
- UITouch触摸
- 什么是触摸:是一个UITouch类型的对象,当用户touch视图时,会自动将触碰物理性的动作,转换成对象存储起来,这个对象就是UITouch对象
- 如何获取touch对象
- 情况一:自定义视图类,重写类中指定方法,在这个方法中,通过传入的参数可以获得touch对象
- 情况二:对于触碰控制器自带的View,在控制器中重写指定方法,通过参数也可以获得touch对象
touchBegan
touchMove
touchesEnded
- 手势
- 将用户物理性的触屏操作转变成了对象存储起来,所有手势的父类UIGestureRecognizer
- 系统将一些有特点的触屏操作封装了不同的手势类型,包括以下几种:
UITapGestureRecognizer
点击UISwipeGestureRecognizer
清扫UILongPressGestureRecognizer
长按UIPanPressGestureRecognizer
拖拽UIPinchPressGestureRecognizer
捏合UIRotationPressGestureRecognizer
旋转
- 如何使用手势?
- 创建指定手势对象,在创建时设置好当该手势发生时系统会自动调用什么方法
- 设置手势的核心属性
- 将创建好的手势添加到某个视图上,当用户在该视图上做了手势对应的动作,手势就会触发
- Tap手势 ( 点击 )
- 核心属性:
- numberOfTapsRequired 需要点击几次
- numberOfTouchesRequired 需要几个点
- numberOfTouches 返回有几个点点击
- 核心属性:
- Swip手势(轻扫)
- 核心属性
- direction 清扫方向
----
以下的手势 和 前面两个不一样,前面两个是一次性手势,手势触发一次,只调用一次时间方法,下面手势是由状态,不同状态都会调用时间方法,有以下状态:
- 核心属性
- 手势触发时: 起始状态
- 手势移动式: 改变状态
- 手势结束时: 结束状态
- LongPress手势(长按)
- 核心属性
- minimumPressDuration 长按所需最小时间
- 核心属性
- Pan(拖拽)
locationInView
:获取的是父视图的绝对位置translationInView
: 获取的是相对于手势开始时的相对位置 (是相对位置)△x △y
- Pinch手势(捏合)
- 核心属性:velocity 缩放速率
- scale 缩放比例
- Rotation旋转
- 核心属性:rotation
- 变形
- 什么时变形:视图发生了位移,旋转,缩放这样的变化叫做变形,如何实现视图的变形.通过修改视图的transform属性,就能完成变形
tranform
- 类型:CGAffineTransform 结构体类型
- 该结构体中包含了9个值,是一个3*3的矩阵,矩阵的对角线上是三个定值不会发生变化,剩下的6个变量是控制变形的,可以借助系统提供的API实现数值的改变
- rotation:旋转
CGAffineTransformMakeRotation
CGAffineTransformRotation
- scale:缩放
CGAffineTranformMakeScale
CGAffineTranformScale
- translation:位移
CGAffineTranformMakeTranslation
CGAffineTranformTranslation
- 带make的函数 都是相对于初始状态
- 不带make是在变形基础上继续位移
CGAffineTransformIdentity
给transform属性赋值该常量,里面所有属性全部清空
- 手势加变形
- pan手势:位移
- rotation手势: 旋转
- pinch手势:缩放
- tap手势:取消所有变形效果
- 手势共存
- 需要哪个手势共存 只要设置该手势的代理人 为当前对象即可
obj -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
- 返回一个BOOL值,为YES即可.
- 需要哪个手势共存 只要设置该手势的代理人 为当前对象即可
清空所有变形 [sender setTranslation:CGPointZero inView:self.view];
- 深入坐标系
- frame:
- CGRect类型
- 作用:定位,视图的坐定点在父视图坐标系对应点的坐标,以及视图在父视图中占据了多大的空间
- bounds
- CGRect类型
- 作用:描述了视图自身的坐标的顶点的值,以及视图自身的尺寸大小
- center
- CGPoint类型
- 描述视图的中心点在父视图坐标系的坐标位置
- transform
- CGAffineTransform类型
- 描述视图的变形状态
frame | bounds | center | transform | |
---|---|---|---|---|
frame | 改变原点:不变;改变大小:变 | 变 | 变 | |
bounds | 改变原点:不变;该大小:变 | 不变 | 不变 | |
center | 变 | 不变 | 不变 | |
transform | 不变 | 不变 | 不变 |
- CoreAnimation层面动画
- CALayer层(显示的基础)
- backgroundColor : 设置背景颜色
- borderWidth : 设置边宽
- cornerRadius : 设置圆角半径
- borderColor : 设置边的颜色
- shadowColor : 设置阴影颜色
- shadowOffset : 设置阴影偏移量
- shadowOpacity :
设置阴影的透明度 默认为零 opacity 只会修改自己``alpha 改变父视图,会带着子视图一起变化
- shadowRadius : 设置阴影的半径
- layer.masksToBounds : 按边缘进行遮罩
- position 位置 (默认是0,0点)
- anchorPoint 锚点 (默认是 0.5,0.5)
- UIView核心的显示功能就是依赖底层的CALayer实现的,每一个UIView都包含了一个CALayer对象,修改了CALayer,会影响显示出来的UIView外观
- CALayer层(显示的基础)
- 如何获取CALayer
- 所有视图都有CALayer的属性,通过.layer即可获取
- 自己创建CALayer对象,添加到视图的layer中
图片CALayer
- 给contents赋值即可
文字CATextLayer
- 给string属性赋值即可
图形CAShapeLayer
- 给path属性赋值CGPath对象
- 变形
- 旋转按照锚点旋转
CATransform3D
类型
- 一个角度转弧度的宏
#define angleToRadian(x) (x) / 180.0 * M_PI
- CADisplayLink定时器
- 用 displayLinkWithTarget 类方法创建
- 需要加到运行循环中 RunLoop
[_link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- displayLink定时器中有一个暂停的属性
paused
.默认是NO
- CALayer的很多属性都有隐式动画,在修改属性时,会自动出现动画效果,可以通过查看头文件中,属性上出现了 animatable这样的说明,意味着该属性有隐式动画
- CAAnimation动画
- CA的动画,只能施加在CAlayer上
- CA动画是假的,视图看着好像位置改变了,但其实没有变
- UIView动画,由于明确了设定了动画的结束视图的状态,所以使徒的数据会随着动画的结束而真的被改变
- CAAnimation 子类
- 子类一:CABasicAnimation 基础动画,设置动画的其实和中点值即可
- 一定要设置keyPath属性,以此说明动画要修改的是什么
- keyPath
- toValue 要用NSValue转换一下
- repeatCount 重复次数
- autoreverses BOOL值 是否回去
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 400)];
- duration 设置时长
anim.removedOnCompletion = NO;
动画结束时,是否把动画从视图上移除anim.fillMode = kCAFillModeForwards;
将视图固定在动画结束时 的位置,还需要配合该属性使用------这个方法要和上面的方法配合使用kCAFillModeBackwards
在动画开始前,只需要将动画加入一个layer,layer便立即进入到动画的初始状态并等待动画的运行kCAFillModeBoth
开始和结束的两种状态都有kCAFillModeRemoved
这个是默认值,也就是说动画开始前和动画结束后动画对layer都没有影响,动画结束后layer会恢复到之前的状态kCAFillModeForwards
在动画结束时,layer停留在动画的结束状态- 子类二:CAKeyframeAnimation 关键帧动画
- 关键帧动画,可以定义动画过程中的细节,所以可以通过values属性,记录中间变化的每一个关键的细节,在每两个关键点中自动做动画
- 子类三:CAAnimationGroup
- 动画组中需要的是CAAnimation,组中动画可以同时运行
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
:动画组的线性函数
- 布局(Layout)
- 什么是布局:是指在一个视图中,如何摆放它的子视图(设置子视图的位置和大小)
- 为什么要用布局:屏幕的尺寸经常会发生变化,使得屏幕可显示的区域也发生变化,于是最开始添加子视图的frame,在新的区域下就不再适用了,需要进行调整,也就是需要重新布局
- 可能导致屏幕大小发生变化的原因:
- 设备不同(3.5寸下的横竖屏,4寸下横竖屏,4.7寸下的横竖屏,5.5寸下横竖屏)
- 各种bar:
- NavigationBar 竖屏是高64个点(20是状态栏),横屏是(52个点)没有状态栏;
- toolBar 竖屏是高44个点,横屏是32个点
- tabBar 49点
- 状态栏: 隐藏
- 来电时:绿色的状态栏
- 录音时:红色的状态栏
- 开启个人热点:蓝色的状态栏
- 键盘
- 如何布局:
- 纯代码布局(古老的方法)- 理念:当屏幕发生变化时,自动执行一段代码,在代码中根据新的屏幕大小重新计算
//此方法是重写父类的方法 在屏幕内容从无到有会自动执行//在屏幕旋转时,也会自动执行-(void)viewDidLayoutSubviews{//self.topLayoutGuide.length 顶部被占据的高度 //self.bottomLayoutGuide.length 底部被占据的高度 };
- AutoResizing 布局- 是什么? iOS5之前自动布局技术,操作简单,API简单,功能也简单,有一定的局限性,很以前的技术- 核心理念:当视图发生变化时,
- AutoLayout(自动布局)
- 在iOS10以前配合SizeClasses技术完成屏幕的适配工作
- 工作原理:通过一些类的"约束constraint"来描述视图的展示位置
- 什么是约束?代表一个条件,只需要设定一些约束,则系统就会根据这一堆约束,自动计算符合约束的frame
- 如何创建约束?
- 方式一:用代码创建
- 方式二:在stroyBoard中 或 xib中可视化配置
- 约束的两个原则:
- 1.描述清楚(x,y,w,h)
- 2.约束不能冲突
- 约束对象:每一个约束条件都是一个约束对象
- 方法一:万能公式法
- 任何一个是视图的约束都可以由下面的等式描述出来,就是要把文字性的描述编程等式中的参数
- 方法二:VFL法(Visual Format Language
- 是一个字符串,具有一定的格式,不同的格式代表不同的约束,并且一个字符串,往往能一次性表达出多个约束
- VFL特殊符号的含义:
- | 代表父视图的边缘
- H:| 代表父视图的左边
- V:| 代表父视图的顶部
- [] 代表一个子视图(控件)
- () 条件
- -x- 代表间隔为x
-
- 代表间隔为标准间隔 8
-
- 通知:完成对象之间的消息传递(观察者模式)
- 实现的核心理念:
- 通知的发送发不知道接收方是谁,是需要将通知发给通知中心即可
- 通知的接收方不知道发送方是谁,只需要提前向通知中心订阅一个通知即可
- 一单通知的发送发真的发出了通知,则由通知中心负责将这个通知推送给所有订阅了该通知的对象们
- 应用:跨界面传值;系统之间的事情,键盘弹起等
- 与代理方式对比:
- 代理只是两个对象之间,私密的消息的传递
- 通知可以是一个对象对多个对象的消息传递,但彼此并不知道对方是谁
- 核心对象
- 通知中心:NSNotificationCenter (单例,系统自己创建好的)
- 通知 NSNotification
- 自定义通知
- 自己写通知的发送方以及接收方
- 系统提供的通知: 键盘通知
- 系统通知,系统会在适当的时候自己发通知,如果我们需要接受,只需要向通知中心注册即可,也就是说我们只需要实现接收方就可以了
- 接受键盘通知:
- 键盘将要显示 UIKeyboardWillShowNotification
- 键盘已经显示 UIKeyboardDidShowNotification
- 键盘将要隐藏 UIKeyboardWillHideNotification
- 键盘已经隐藏 UIKeyboardDidHideNotification