参考:iOS基础进阶班合辑-大神推荐
本文是上面课程的摘要,只用于自己快速浏览.
目录
- 01 iOS大神班-UI基础-第一章(上)
- 02 iOS大神班-UI基础-第一章(下)
- 03 iOS大神班-UI基础-第二章(上)
- 04 iOS大神班-UI基础-第二章(中)
- 06 iOS大神班-UI基础-第三章
- 07 iOS大神班-UI基础-第四章
- 08 iOS大神班-UI基础-第五章(上)
- 09 iOS大神班-UI基础-第五章(下)
- 11 iOS大神班-UI基础-第六章(下)
- 12 iOS大神班-UI基础-第七章(上)
- 13 iOS大神班-UI基础-第七章(中)
- 14 iOS大神班-UI基础-第七章(下)
- 15 iOS大神班-UI基础-第八章(上)
- 16 iOS大神班-UI基础-第八章(下)
- 17 iOS大神班-UI基础-第九章(上)
- 18 iOS大神班-UI基础-第九章(下)cell的动态高度 frame方式
- 19 iOS大神班-UI基础-第十章(上)cell高度的处理
- 20 iOS大神班-UI基础-第十章(下)左滑删除,编辑模式
01 iOS大神班-UI基础-第一章(上)
【录播】第一个iOS程序03-storyboard文件的简单认识(11分钟)
描述软件界面
描述界面间的跳转关系
storyboard界面的size设置
4英寸屏幕
4.7英寸屏幕
5.5英寸屏幕
02 iOS大神班-UI基础-第一章(下)
【录播】总结01-stroyboard的认识(简单的启动原理)(8分钟)
stroyboard文件的入口文件,有一个箭头指向
配置使用哪一个stroyboard文件
【录播】总结02-控制器.IB(9分钟)
控制器
控制器负责软件界面的创建和销毁
每一个控制器都会专门管理一个软件界面
Interface Builder
IBOutLet
IBAction
xib文件
storyboard文件时xib文件的升级版
iOS4以前往xib文件拖控件需要打开一个软件叫Interface Builder
后来xcode默认将Interface Builder集成了进来
所以类型前面会有一个前缀IB,这是历史遗留问题
面试问道是否会用Interface Builder,就是stroryBoard和xib
03 iOS大神班-UI基础-第二章(上)
【录播】资源引用问(21分钟)
Destination
Copy items if needed
将资源拷贝一份到当前目录下
Added folders
Create groups
之前不会创建真正的文件夹
现在会创建文件夹,但打包时在Bundle包内不会创建文件夹,而是将资源放在根目录下
Create folder references
会创建真正的文件夹
打包后Bundle包内会产生文件夹,资源路径为根目录/文件夹/资源
Add to targets
将资源添加到Bundle包内
不勾选,打包后,Bundle包内找不到资源
【录播】UIImageView01-帧动画的基本使用(18分钟)
imageView.animationImages = @[]
imageView.animationRepeatCount = 1(0代表无限次)
[imageView startAnimating]
【录播】UIImageView02-抽取重复的代码(17分钟)
重复代码抽取
imageView.animationDuration = count * 0.5;
播放完大招动画,播放站立的动画,使用perform:selector:afterDelay:
【录播】UIImageView03-播放音频文件(19分钟)
NSURL urlWithString
“https://xxxx”
“file:///var/xxxx”
avplayer
self.player = [AVPlayer playerWithURL:url]
[self.player play]
获取mainBundle下的资源
【录播】小结(6分钟)
以上内容的总结
04 iOS大神班-UI基础-第二章(中)
【录播】UIImageView04-加载无缓存图片(15分钟)
[UIImage imageNamed:@“”]//会产生缓存
[UIImage contentOfFile:@“”];//不会产生缓存
放在Assets文件中的图片只能使用imageNamed访问,所以一定有缓存
【录播】UIImageView小总结(4分钟)
以上内容的总结
06 iOS大神班-UI基础-第三章
【录播】instancetype(9分钟)
instancetype
只能作为返回值,不可做参数,不可做类型定义变量
有类型检查
自己理解:表示当前类的实例类型或子类类型
id
可做返回值,可做参数,可做类型定义变量
无类型检查
代指所有类型,void*
07 iOS大神班-UI基础-第四章
//提供一篇参考文章:https://www.jianshu.com/p/c138db1c0e57
【录播】xib文件的基本使用(23分钟)
xib与storyboard
相同点
都使用interface builder工具来编辑
本质都是转换成代码
不同点
xib是轻量级,用来描述局部UI界面
storyboard是重量级,描述多个界面及界面间的跳转关系
加载nib文件
xib文件 -> nib文件
NSArray * array = [[NSBundle mainBundle] loadNibNamed:@"" owner:nil options:nil];
UINib * nibObj = [UINib nibWithNibName:@"" bundle:[NSBundle mainBundle]];
NSArray * array =[nibObj instantiateWithOwner:nil options:nil];
xib文件内控件的尺寸
创建时的大小就是默认尺寸
代码可以修改尺寸
【录播】使用xib自定义商品控件(23分钟)
一个控件使用一个xib文件
如何获取子控件
方法一:循环遍历
多个相同的子控件无法区分
浪费性能
方法二:通过tag
使用者过于关心控件的内部细节
【录播】自定义view封装xib设置数据(27分钟)
绑定类文件
xib文件绑定具体的类文件,子控件作为属性
子控件变为类的属性,给属性赋值
还可以创建一个model,使用model给属性赋值
自定义xib文件及类文件封装
XMGShopView * shopView = [XMGShopView shopView]
shopView方法内部,封装了获取nib文件内控件
思考:绑定后[[XMGShopView alloc] init] 是否会显示出nib文件内的控件。不会
XMGShopView * shopView = [XMGShopView shopViewWithShopModel:model]
08 iOS大神班-UI基础-第五章(上)
【录播】xib的使用注意点(11分钟)
initWithFrame:
initWithCoder: //通过xib或storyBoard创建,初始化的时候调用
awakeFromNib: // 通过xib或storyBoard创建,加载完毕后的时候调用
【录播】xib的加载原(22分钟)
加载原理
检查文件绑定的类型
调用initWithCoder:方法
设置frame,背景色等属性
同样方式检测子控件
检测子控件是否有连线
[[XMGShopView alloc] init] 不会加载xib的内容
【录播】示例程序演示xib自定义控件(15分钟)
提供自定义的接口
提供自定义的数据模型初始化
【录播】显示隐藏一个控件(16分钟)
hidden属性
alpha属性
【录播】渐变动画(18分钟)
动画种类
帧动画
渐变动画
核心动画
转场动画
渐变动画
头尾式实现
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2];
//变换的代码
[UIView commitAnimations];
block方式
[UIView animateWithDuration:2 animations:^{/*变换的代码*/}];
[UIView animateWithDuration:2 animations:^{} completion:^(BOOL finished) {}];
[UIView animateWithDuration:2 delay:1 options:kNilOptions animations:^{} completion:^(BOOL finished){}];
是否可以做渐变动画
hidden不可以
alpha是可以的
【录播】渐变动画的应用(11分钟)
用block方式封装了一个HUD
-(void)showHUD:(NSString*)text;
【录播】半透明指示器(13分钟)
设置半透明背景
设置label.alpha值文字也会跟着半透明
label.alpha = 1;然后设置背景色的透明值
创建带透明值的颜色
UIViewAnimationOptions
渐变动画样式比如快进慢出,慢进快出等
【录播】按钮的内部细节01-自定义按(26分钟)
在viewDidLoad方法内创建按钮,打印按钮的子控件为空
懒加载
只有再显示按钮的时候才会创建子控件
自定义button控件
调整imageView和titleLabel的位置,子类实现
-(CGRect)imageRectForContentRect:(CGRect)contentRect
-(CGRect)titleRectForContentRect:(CGRect)contentRect
方式二:
在-(void)layoutSubviews;方法内调整子控件
self.imageView.frame = xxx;
self.titleLabel.frame = xxx;
【录播】按钮的内部细节02-通过按钮自定义商品控(12分钟)
用按钮替换自定义的商品图片
禁止按钮的点击:self.enable = NO;
禁止状态下不调整图片变暗:self.adjustsImageWhenDisabled = NO;
【录播】按钮的内边距(15分钟)
按钮的内边距inset
content:图片文字整体调整
image:只调整图片
title:只调整文字
自定义与内边距
小的调整建议使用内边距(通过调整也能实现自定义的效果)
大的调整建议使用自定义
09 iOS大神班-UI基础-第五章(下)
【录播】过代码拉伸图片(23分钟)
控件放大时背景图片较小,圆角效果很难看
使用可拉伸图片
UIImage * image = [UIImage imageNamed:@""];
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
- (UIImage *)resizableImageWithCapInsets: resizingMode:
拉伸模式
UIImageResizingModeTile//平铺
UIImageResizingModeStretch//拉伸
另外的一种拉伸方式(了解,已不建议使用)
- (UIImage *)stretchableImageWithLeftCapWidth: topCapHeight:;
【录播】封装图片拉伸01-工具类(12分钟)
将拉伸图片的代码封装成一个工具类
【录播】封装图片拉伸02-内存分析(6分钟)
UIImage * image = [UIImage imageNamed:@“xx”];
image = [image resizableImage…];
分析以上代码的内存分配
【录播】封装图片拉伸03-分类(4分钟)
将拉伸图片的代码封装成一个UIImage的分类
【录播】直接修改图片(8分钟)
使用Assets.xcassets管理图片,在内部可以对图片进行可拉伸配置
11 iOS大神班-UI基础-第六章(下)
【录播】利用UIScrollView实现内容缩放(13分钟)
遵从代理,设置代理: scrollView.delegate = self;
设置缩放比
scrollView.maximumZoomScale = 2.0;
scrollView.minimumZoomScale = 0.5;
实现协议返回要缩放的控件
-(UIView *)viewForZoomingInScrollView:
scrollView知道在它上边有缩放手势,但不知道作用于谁,通过代理告知
【录播】利用UIScrollView实现内容缩放的补充(5分钟)
在模拟器上使用缩放手势
按住option键,移动鼠标
按住option+shift键,移动缩放手势的起始位置
正在缩放时调用
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
12 iOS大神班-UI基础-第七章(上)
【录播】屏幕适配的介绍(了解)(15分钟)
系统适配
针对不同版本的操作系统进行适配
iOS10添加了新功能,iOS9没有,就需要适配
屏幕适配
不同大小的屏幕尺寸进行适配
横屏竖屏的适配
手机
一般软件只支持竖屏
一般游戏软件只支持横屏
iPad
横屏与竖屏
可能横屏与竖屏的界面布局大不同
像素与点
用户眼中看到的是像素,像素越多越清晰
开发者眼中看到的是点,点又是由像素构成的
非retina屏幕一个点就是一个像素,retina屏幕1个点是4个像素
不同手机屏幕的点与像素
3.5inch(iphone/3G/3GS)
像素:320*480
点:320*480
3.5inch(iphone4/4S)
像素:640*960
点:320*480
4.0inch(iphone5/5C/5S)
像素:640*1136
点:320*568
4.7inch(iphone6)
像素:750*1334
点:375*667
5.5inch(iphone6 plus)
像素:1242*2208
点:414*736
9.7inch(iPad3/4/Air)
像素:1536*2048
点:768*1024
7.9inch(iPad mini)
像素:768*1024
点:768*1024
7.9inch(iPad mini2)
像素:1536*2048
点:768*1024
【录播】屏幕适配的发展历史(了解)(11分钟)
以前只有一个尺寸320*480
所以会固定使用320和480这两个尺寸
获取屏幕尺寸
[UIScreen mainScreen].bounds.size.width;
[UIScreen mainScreen].bounds.size.height;
AutoresizingMask
iphone5时代屏幕尺寸发生了变化,AutoresizingMask派上了用场
Autolayout(iOS6开始出现的技术)
iPhone 5-iPhone 5s首次搭载iOS6系统,但为什么不使用Autolayout?
一是还要支持iOS5
二是Autolayout不成熟
iPhone 6 时代屏幕的宽度也变化了是时候抛弃AutoresizingMask,使用Autolayout
一是不用支持iOS5了
二是屏幕适配的多样性来说AutoresizingMask已经过时了
Size Classes
【录播】Autoresizing(在storyboard中使用)(16分钟)
使用场景
storyboard
xib
代码
关系
autoresizingMask 与 Autolayout 不能共存
Size Classes 依赖于 Autolayout
autoresizing六条线的作用
外部四条线表示距离父视图的距离
上边线线优先级高级下边线
左边线的优先级高于右边线
内部两条线代表随父视图的宽或高比例变化
代码加载storyboard
UIStoryboard * story = [UIStoryboard storyboardWithName:@"AutoresizingTest" bundle:nil];
UIViewController * vc = [story instantiateInitialViewController];
【录播】Autoresizing的实际应用(3分钟)
让子视图充满父视图跟随父视图大小变换
将子视图充满父视图
选中上边线和左边线
选中中间两条线
【录播】Autoresizing(在代码中使用)(9分钟)
redView.autoresizingMask = xx | xx | xx;
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,//左边可变,即右边固定
UIViewAutoresizingFlexibleWidth = 1 << 1,//宽度可变
UIViewAutoresizingFlexibleRightMargin = 1 << 2,//右边可拉伸,即左边固定
UIViewAutoresizingFlexibleTopMargin = 1 << 3,//上边可变,即下边固定
UIViewAutoresizingFlexibleHeight = 1 << 4,//高度可变
UIViewAutoresizingFlexibleBottomMargin = 1 << 5 //下边可变,即上边固定
【录播】Autolayout的基本使用01(22分钟)
autolayout
自动布局技术,专门用来布局UI界面的
iOS6开始有的技术,xcode4不给力,适配iOS5,没有得到推广
iOS7,xcode5开始,效率得到提升
从iphone6开始普遍使用
苹果也推荐Autolayout,可以更好更方便的适配屏幕
autolayout和autoresizing
autoresizing只能解决子控件和父控件之间的相对关系
autolayout可以解决任何控件之间的关系
autolayou的两个核心概念
约束
storyboard
简单使用
添加约束
修改约束
constrain to margins的作用
不勾选该选项
xib
代码
参照
【录播】Autolayout的基本使用02(7分钟)
参照
各个方向默认是跟自己最近的最为参照
【录播】Autolayout的基本使用03-警告和错误(7分钟)
警告
可以正常运行,只是现在xcode显示的跟实际有差别
报错
不可以正常运行
约束不够,不能确定位置
约束过多,形成冲突
13 iOS大神班-UI基础-第七章(中)
【录播】Autolayout(基本练习01)(14分钟)
建议先搞定一个,再搞定另外一个
对齐
等宽、等高
水平、垂直间距
参照是离最近的控件
【录播】Autolayout的万能公式(12分钟)
obj1.property1 = (obj2.property2 * multiplier) + constant value
【录播】Autolayout的使用补充(12分钟)
对齐操作
一个控件向另一个控件拖线(control)
选中两个(commond)
对齐方式
上、下、左、右 对齐
水平居中、垂直居中
在容器中水平居中,垂直居中
【录播】Autolayout(基本练习02)(8分钟)
控件二是控件一宽度的一半
想让控件二的宽度等于控件一
改变公式里的系数
对齐
控件二的左边与控件一的x中心点对齐
先让控件二与控件一的左边对齐,然后改变控件二左边与控件一的对齐点为中心点
【录播】Autolayout(高级练习)(14分钟)
4块平分屏幕
【录播】通过autolayout实现UIlabel包裹内(11分钟)
设置位置约束
设置宽度约束<=固定值
不用设置高度约束,但需要设置自动换行
【录播】父控件跟随子控件内容进行伸缩(8分钟)
父视图位置确定,宽度确定
子视图位置确定,宽度确定
子视图与父视图底部距离确定
bottom space to container
【录播】代码实现Autolayout(了解)(20分钟)
代码创建约束
autoresizing与autolayout不兼容
view默认开启了autoresizing的width和height
关闭autoresizing转autolayout
原理是万能公式
obj1.property1 = (obj2.property2 * multiplier) + constant value
约束添加的原则
同层级,添加到父view
不同层级,添加到最近的共同父view
有层次关系的两个view,添加到层次较高的父view
【录播】VFL实现Autolayout(了解)(15分钟)
VFL
Visual Format Language
语法示例
NSDictionary * views = @{@"redView":redView};
NSDictionary * metrics = @{@"space":@20,@"height":@40};
@“H:|-20-[redView]-20-|”;
@“V:[redView(40)]-20-|”;
@“H:|-space-[redView]-space-|”;
@“V:[redView(height)]-space-|”;
【录播】VFL实现Autolayout的练习(了解)(14分钟)
语法示例
@"H:|-space-[redView(==blueView)]-space-[blueView]-space-|"
@"V:[blueView(height)]-space-|";
注意
vfl语言无法描述的用万能公式添加
options参数的作用
水平方向,可以顶部对齐,底部对齐
垂直方向,可以左对齐,右对齐
当view过多时,映射可以使用下面的方式
NSDictionaryOfVariableBindings(redView,blueView);
14 iOS大神班-UI基础-第七章(下)
【录播】约束的优先级(12分钟)
vfl的方式和万能公式
本质都是代码
vfl具有局限性,比如设置宽度是另一个的一半不支持
会报错:[redView(==0.5*blueView)]
约束的优先级
约束的优先级越高越先生效
【录播】通过代码修改约束,约束动画(10分钟)
修改约束
用约束就不要用frame
约束也是对象,也可以拖线
约束修改动画
约束不属于UIView框架,渐变动画不起作用
调用[self.view layoutIfneeded]
【录播】Masonry的使用(20分钟)
masonry的使用
关闭autoresizing
本质是万能公式
简写
multipliedBy(1)可以省略不写
offset(0)可以省略不写
mas_equalTo(self.view.mas_top)的简写及省略
and关键字的用法及省略
.left.and.right
.left.right
几个其它用法
make.center.mas_equalTo(bluView);
make.centerX.mas_equalTo(bluView);
make.centerY.mas_equalTo(bluView);
make.size.mas_equalTo(bluView);
make.edges.mas_equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));
【录播】Masonry的使用02(6分钟)
等于的用法与区别
equalTo(@100)
mas_equalTo(100);
【录播】Masonry的练习(13分钟)
Masonry练习
底部红蓝练习
宏定义去除简写
一定要放在头文件之前
#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS
更新约束
mas_updateConstraints
删除后重置约束
mas_remakeConstraints
约束的权限
.priority(750)
with关键字
.with.offset(30)
.offset(30)
and关键字的用法及省略
.left.and.right
.left.right
15 iOS大神班-UI基础-第八章(上)
【录播】autolayout知识点回(24分钟)
分享了一个笔记软件gitbook
对autolayout知识点进行了回顾
【录播】UITableView的基本使用(33分钟)
UITableView两种样式
UITableViewStyleGrouped
UITableViewStylePlain
UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:
-(NSInteger)tableView: numberOfRowsInSection:
-(UITableViewCell *)tableView: cellForRowAtIndexPath:
【录播】展示多组数据(28分钟)
section的头尾标题
-(NSString *)tableView: titleForHeaderInSection:
-(NSString *)tableView: titleForFooterInSection:
【录播】展示多组数据(使用模型改进(33分钟)
懒加载思想
模型管理数据的思想
用模型取代字典
写代码时有输入提示
有错误提示
【录播】展示多组数据(复杂plist解析)(25分钟)
数据跟业务代码分离
数据可以保存在一个plist文件内
字典转模型
setValuesForKeysWithDictionary://只能转一级
自己实现
【录播】展示多组数据(复杂plist解析总结)(3分钟)
复杂的plist数据解析
一层一层的解析
所有的字典都转为模型
字典在数组内,转为模型后仍在数组内
plist的好处
方便管理数据
【录播】展示单组数据(11分钟)
section的数量设置为1就是单组数据
- (NSInteger)numberOfSectionsInTableView:
该代理方法不是必须实现,默认返回1
【录播】展示酒数据(19分钟)
cell的三个子视图
imageView
textLable
detailTextLable
cell的四种样式
default
subtitle
value1
value2
cell.accessoryType
【录播】UITableView的常见属性(13分钟)
self.tableView.rowHeight = 70;//默认44
self.tableView.sectionHeaderHeight = 70;
self.tableView.sectionFooterHeight = 70;
self.tableView.separatorColor = ;
self.tableView.separatorStyle = ;
self.tableView.headerView = ;
self.tableView.footerView = ;
【录播】UITableViewCell的常见属性(13分钟)
cell.accessoryType
UITableViewCellAccessoryDisclosureIndicator,
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryCheckmark,
UITableViewCellAccessoryDetailButton
cell.accessoryView
cell.selectionStyle
UITableViewCellSelectionStyleNone
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray,
UITableViewCellSelectionStyleDefault
cell.backgroundColor
cell.backgroundView
cell.selectedBackgroundView
16 iOS大神班-UI基础-第八章(下)
【录播】contentView(9分钟)
contentView
imageView
textLable
detailTextLable
为什么需要contentView
整体移动三个控件
三个控件的创建方式是懒加载
【录播】UITableView的代理方法(17分钟)
UITableViewDelegate
-(void)tableView: didSelectRowAtIndexPath:
-(void)tableView: didDeselectRowAtIndexPath:
-(UIView *)tableView: viewForFooterInSection:
-(UIView *)tableView: viewForHeaderInSection:
- (CGFloat)tableView: heightForHeaderInSection:
-(CGFloat)tableView: heightForFooterInSection:
【录播】UITableViewControlle(18分钟)
UITableViewController
遵守了两个协议
self.view
self.tableView
【录播】性能优化(存在的问题(13分钟)
tableView存在的问题
只有有一个cell进入视野就会调用cellForRowAt..
如果在这个方法内创建cell,上划或下拉只要有新的cell出现,必定是新创建的
存在的问题就是重复创建cell,浪费内存,浪费性能
【录播】性能优化(思路)(16分钟)
离开视野的cell放入缓存池
放入缓存池时要创建一个标识,
将要显示新的cell,先去缓存池中通过标识找,标识的作用就是防止取到不同类型的cell
找到使用缓存池中cell
找不到创建新的cell
【录播】性能优化(实现)(9分钟)
[self.tableView dequeueReusableCellWithIdentifier:@""]
【录播】性能优化(代码优化)(18分钟)
static NSString * cellId = @"wine";
静态局部变量在内存中只占用一份
哪些代码放在if里边
哪些代码放在if外边
【录播】性能优化(注册cell)(18分钟)
dequeueReusableCellWithIdentifier
第一步:根据ID标识去缓存池中取cell,有就返回cell
第二步:如果没有取到,会看该ID有没有注册cell,没有注册返回nil
第三步:如果注册了,会自动创建cell并绑定该标识ID,将cell返回
注册cell的缺点
应为cell是在dequeue方法内创建,没法选择cell类型
可以通过自定义cell解决
17 iOS大神班-UI基础-第九章(上)
【录播】索引条(33分钟)
通过汽车列表的例子对前边内容回顾
cell的重复使用
隐藏状态栏:prefersStatusBarHidden
-(NSArray<NSString *> *)sectionIndexTitlesForTableView:
[数组 valueForKeyPath:]的使用
索引属性
self.tableView.sectionIndexColor;
self.tableView.sectionIndexBackgroundColor;
【录播】自定义cell简单介绍(13分钟)
自定义等高cell四种方式
纯代码frame
纯代码autoLayout
xib
storyboard
自定义不等高cell四种方式
纯代码frame
纯代码autoLayout
xib
storyboard
思路
在系统cell的基础上添加新的view
完全使用自己创建的cell
【录播】自定义等高的cell-纯代码-frame01(17分钟)
两个方法
initWithframes...(cell的初始化不用这个方法)
initWithStyle...(用这个)
layoutSubviews
通过注册的方式创建cell
也是通过initWithStyle这个方法
view属性使用weak
subView是添加到contentView上
【录播】自定义等高的cell-纯代码-frame02(17分钟)
layoutSubviews方法内计算位置和size
各个控件的数组最好能联动
【录播】自定义等高的cell-纯代码-frame03(17分钟)
字典转模型
懒加载
set方法
模型传递数据
【录播】自定义等高的cell纯代码frame04(10分钟)
为什么在layoutSubviews计算位置和size
好用的方法
CGRectGetMaxX(frame)
CGRectGetMaxY(frame)
【录播】自定义等高的cell-纯代码-Autolayout(16分钟)
给子控件添加约束时,子控件应该已经被添加到父控件上了
确定一个控件一般需要四个约束
【录播】字典转模型框(23分钟)
字典转模型三方框架
Mantle
所有模型都必须继承自MTModel
jSONModel
所有模型都必须继承自jSONModel
MJExtension
不需要强制继承任何其他类型
使用方式
//传入字典数组
[XMGCarGroup mj_objectArrayWithKeyValuesArray:nil];
//plist文件路径
[XMGCarGroup mj_objectArrayWithFile:@""];
//pist文件名称
[XMGCarGroup mj_objectArrayWithFilename:@""];
//嵌套的model类型,告诉框架的方式一
//在模型内实现下面方法
+(NSDictionary *)mj_objectClassInArray{
return @{@"cars":[XMGCar class]};
}
//嵌套的model类型,告诉框架的方式二
//在模型内实现下面方法
+(NSDictionary *)mj_objectClassInArray{
return @{@"cars" : @"XMGCar"};
}
//嵌套的model类型,告诉框架的方式三
[XMGCarGroup mj_setupObjectClassInArray:^NSDictionary *{
return @{@"cars" : @"XMGCar"};
}];
[XMGCarGroup mj_objectArrayWithKeyValuesArray:nil];
【录播】自定义等高的cell-xib01-基本实现(16分钟)
创建xib文件
拖一个UITableVeiwCell控件
添加子控件,设置约束
绑定类,拖属性,model设置属性的数据
loadNib方式创建cell
缓存池没有自己创建
【录播】自定义等高的cell-xib02-优化(13分钟)
放入缓存池的方式一
在xib文件内设置cell的identifier
用loadNibName创建的cell,会被放入缓存池
放入缓存池的方式二
//根据id注册对应的class
//创建cell时会调用initWithStyle,所以不适用于xib形式
Class cls = [XMGCell class];
[self.tableView registerClass:cls forCellReuseIdentifier:@"xmgID"];
//根据id注册对应的xib文件
UINib * nib = [UINib nibWithNibName:NSStringFromClass([XMGCell class]) bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:@"xmgID"];
//先去缓存池找 xmgID 这种cell
//如果没有,查看是否有注册类,有注册类调用initWithStyle方法创建cell
//如果没有注册类,查看是否有注册xib,有注册创建cell返回
UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier:@"xmgID"];
关于cell的宽高
xib文件内设置的cell的宽高不起作用
宽充满整个tableView
高默认44,需要通过rowHeight或代理来设置
18 iOS大神班-UI基础-第九章(下)
【录播】不同类型的cell共存(XIB)(7分钟)
通过注册的不同的id,dequeue出不同类型的cell
【录播】自定义等高cell-storyboard01-基本实现(16分钟)
在storyboard的控制器内的tableView的cell上直接操作
绑定cell
设置cell的identifier
dequeueReusableCellWithIdentifier
缓存池是否有
是否注册了class
是否注册了xib
去storyboard中找
【录播】自定义等高cell-storyboard02-补(10分钟)
dequeueReusableCellWithIdentifier原理
storyboard中给cell设置id
动态cell,cell的个数是动态的
静态cell,cell的个数是固定的
【录播】自定义分隔线(6分钟)
去除系统的分割线
类型设置为none
添加自己的分割线
最小的设置单位为1个高度
要想显示细点可以设置透明度,比如设置为0.3,视觉差会让其看起来细点
【录播】静态cell(13分钟)
故事版UITableViewController才可以设置静态cell和动态cell
静态cell数量是固定的,不如设置界面
先弄好一个,再弄其它的
点击事件与动态cell一样,都是通过代理方法
【录播】自定义不等高cell-frame02-添加子控(22分钟)
自定义不等高cell四种方式
纯代码frame
纯代码autoLayout
xib
storyboard
tableView的dataSource协议实现
定义一个数据模型
字典转模型
自定义cell
initWithStyle...
layoutSubViews
setStatus://将model的数据传入
【录播】自定义不等高cell-frame02-添加子控件(9分钟)
添加子控件的原则
有可能显示的控件都添加进去
根据情况显示或隐藏控件
【录播】自定义不等高cell-frame03-设置数据(10分钟)
setStatus
设置数据
bool类型建议增加一个 getter = isVip
【录播】自定义不等高cell-frame04-计算子控件的尺(38分钟)
使用frame的流程
初始化方法内创建对象
layout方法内确定位置大小
set方法内设置数据
计算字符串的宽高(适用于一行)
NSString * str = [[NSString alloc] init];
NSDictionary * attribute = @{NSFontAttributeName:[UIFont systemFontOfSize:16]};
CGSize size = [str sizeWithAttributes:attribute];
计算字符串的宽高(适用于多行)
CGSize maxSize = CGSizeMake(100, MAXFLOAT);
CGSize realSize= [str sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:maxSize];
//上面方法已经不建议使用,使用下面的方法
NSDictionary * attribute = @{NSFontAttributeName:[UIFont systemFontOfSize:16]};
[str boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attribute
context:nil]
【录播】自定义不等高cell-frame05-计算cell的高度(27分钟)
拿到某一个cell
UITableViewCell * cell = [self.tableView cellForRowAtIndexPath:indexPath];
计算cell的高度
方案一:不可行,循环调用
在-(CGFloat)tableView:heightForRowAtIndexPath:方法内
拿到cell:[self.tableView cellForRowAtIndexPath:indexPath]
通过cell最后一个子控件的 y + 控件的h计算cell的高度
方案二:不可行,先调用确定cell高度的函数,再调用layoutSubView
在cell内部的layoutSubView计算好高度,将高度保存到cell的数据模型
在-(CGFloat)tableView:heightForRowAtIndexPath:方法内返回高度
方案三:可行,但同样的数据在方法内计算了一遍,在cell内又计算了一遍
在-(CGFloat)tableView:heightForRowAtIndexPath:方法内
根据模型数据计算一遍cell的高度,返回cell的高度
19 iOS大神班-UI基础-第十章(上)
【录播】自定不等高的cell-frame-性能优化(24分钟)
layout方法调用很频繁
返回cell的height的方法调用也很频繁
所以将计算放在这个方法内频繁的重复计算会影响性能
下面的方式可以保证height只计算一次
将算好的数据存入模型,imageFrame,iconFrame,...
将算好的高度也存入模型
在返回cell的高度的方法内调用,status.height
在height的set的方法内,就算height并赋值给status.height
注意:
只需计算一次的数值,可以先判断是否有值
没有值就就计算
有值就直接返回
【录播】自定不等高的cell-frame-补充(16分钟)
调用顺序
先调用返回cell高度的方法
再调用返回cell的方法
最后调用cell的layoutSubView方法
layoutSubView方法是一个控件将要显示的时候才会调用
注意cell的循环利用导致的问题
比如隐藏vip的图标,下面这两个都得写
self.isVip = yes;
self.isVip = no;
【录播】自定不等高的cell-frame-总结(10分钟)
cell的数据模型设计
具体数据
数据对应的控件的frame
cell的高度
另外一个思路
搞两个数据模型
一个是具体数据
一个是frame和height
MVVM的设计模式
【录播】自定不等高的cell-storyboard01-无配图(24分钟)
self-sizing技术(自己计算自己的尺寸,iOS8开始支持的)
告诉tableView所有的cell的真实高度是自动计算的(根据设置的约束自动计算)
self.tableView.rowHeight = UITableViewAutomaticDimension;
先要给一个估算高度
self.tableView.estimatedRowHeight = 44;
在约束里label可以不用设置宽和高
cell最底部的子控件与cell建立联系
【录播】自定不等高的cell-storyboard02-有配图(14分钟)
视图隐藏只是看不见,但占位还是存在的
方案一:不可行约束的优先级不能二次修改
配图与底部的约束的优先级是1000
label与底部的约束的优先级是700
配图隐藏时,交换优先级
方案二:
将配图控件的高度变为0
高度变为0时有两个约束会产生警告
通过修改其中一个约束的优先级来消除警告
【录播】自定不等高的cell-storyboard03(25分钟)
由于self-sizing技术(自己计算自己的尺寸,iOS8开始支持的)
那么怎么支持iOS8之前的系统(这种方式了解)
1.界面仍然用storyBoard
添加子控件的约束
不添加最后一个子控件与cell之间的约束关系
2.在计算高度的代理方法内
访问缓存池,取出一个cell,这个cell的作用就是计算出一个高度
给cell设置的数据
cell设置数据后,由于约束最终仍然是转为代码,此时就有了frame
拿到最后一个子控件的y和height,计算出cell的高度
返回cell的高度
3.上边设置好后,显示还是有问题
原因一是,cell没有显示时,autolayout是不会计算frame的
所以需要强制刷新,[cell layoutIfNeeded]
原因二是,label控件没有显示时,是不会给最大布局宽度赋值的
lable只要有个位置,就会根据内容自动计算宽度和高度
lable值所以能自动计算高度是因为最大布局宽度,有了这个宽度才能计算高度
label.preferredMaxLayoutWidth = xxx;
4.存在的问题
高度代理方法的调用很频繁,从缓存池取cell的操作有可能会创建cell
将cell搞成一个全局变量,存在就不再取了,节省性能开销
【录播】估算高度的作用(12分钟)
估算高度的作用:性能优化
tableView继承自scrollView
需要知道scrollView的内容高度来显示滚动条
内容的高度就是所有cell的高度之和,所以heightForRow...一开始会都调用一遍
当我们设置了估算高度之后,内容高度就可以估算出来一个估算值,不需要每一个都调用,可以在显示的时候再调用
估算高度也有代理方法
估算高度的值的大小对heightForRow...方法调用次数的影响
估算值越高,调用次数越少
估算值越少,调用次数越少
【录播】封装cell的高度(6分钟)
获取cell的高度,可以在模型内提供一个接口
由于heightForRow...调用很频繁
将可以放在其它地方的代码,拿出来
避免重复的计算,提高性能
【录播】数据刷新01-全局刷新(37分钟)
添加
操作数据源
[self.tableView reloadData];
全局刷新,能看得见的cell,都会刷新一遍
删除
操作数据源
[self.tableView reloadData];
更新
操作数据源
[self.tableView reloadData];
【录播】数据刷新02-局部刷(6分钟)
局部刷新
self.tableView reloadSections: withRowAnimation:
self.tableView reloadRowsAtIndexPaths: withRowAnimation:
20 iOS大神班-UI基础-第十章(下)
【录播】数据刷新03-添加和删除的局部刷新(6分钟)
添加行的局部刷新
self.tableView insertRowsAtIndexPaths: withRowAnimation:
删除行的局部刷新
self.tableView deleteRowsAtIndexPaths: withRowAnimation:
【录播】左滑删(10分钟)
#pragma mark - UITableViewDelegate
//只要实现了该方法就实现了左滑删除功能
-(void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath{
[self.dataSource removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
//修改默认的Delete文字
//可以不实现该方法,只需要进行本地化就可以
-(NSString *)tableView:(UITableView *)tableView
titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
return @"删除";
}
【录播】左滑cell出现多个按钮(18分钟)
//自定义左滑按钮,实现了该方法,系统默认的就可以不实现了
-(NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView
editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewRowAction * action = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault
title:@"删除"
handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
}];
UITableViewRowAction * action1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault
title:@"关注"
handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
//退出编辑模式
self.tableView.editing = NO;
}];
return @[action,action1];
}
【录播】编辑模式(5分钟)
进入编辑模式(左侧出现减号)
self.tableView.editing = YES;
退出编辑模式
self.tableView.editing = NO;
点击取反
self.tableView.editing = !self.tableView.editing;
添加动画
[self.tableView setEditing:!self.tableView.editing animated:YES];
【录播】批量删除(19分钟)
在编辑模式下允许多选
self.tableView.allowsMultipleSelectionDuringEditing = YES;
获取选中的行
self.tableView.indexPathsForSelectedRows;
开发原则
数组不能一边遍历一边删除
【录播】自定义批量删除01-分析(21分钟)
在系统cell的基础上在右侧添加一个对勾图片
【录播】自定义批量删除02-通过模型决定界面的显示(17分钟)
更改cell的样式
从数据源的model入手
【录播】自定义批量删除03-删除(6分钟)
遍历数据源,将标记的数据删除
遍历存在性能问题
如何添加动画?
【录播】MVC简单介(6分钟)
M:model
V:View
C:Controller
tableView是典型的MVC的设计模式
model改变,view改变
性能优化
避免重复创建实例对象
避免重复计算
行者常至,为者常成!