JHHK

欢迎来到我的个人网站
行者常至 为者常成

课程1 iOS基础进阶班(第一部分)-大神推荐

参考:iOS基础进阶班合辑-大神推荐
本文是上面课程的摘要,只用于自己快速浏览.

目录

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改变
        

性能优化
    避免重复创建实例对象
    避免重复计算


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.