JHHK

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

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

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

目录

01 iOS大神班-UI进阶-第一章(上)

【录播】pch文件简介(15分钟)
    pch文件的作用
        存放公有宏
        存放公有头文件

    pch文件的原理
        会将pch文件的内容拷贝到类文件内


【录播】pch文件自定义Log(20分钟)

    自定义log

    注意有C文件要做判断
        在每一个OC文件内部都有隐式的一个宏 __OBJC__ 

02 iOS大神班-UI进阶-第一章(下)

【录播】应用程序启动原理(19分钟)

    UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        第一个参数:参数个数
        第二个参数:参数列表
        第三个参数:nil,默认是 @"UIApplication",内部会创建一个应用程序对象
        第四个参数:UIApplication对象的代理,内部会创建一个代理对象

    应用程序启动流程
        1.可执行文件载入内存
        2.执行main函数
        3.执行UIApplicationMain
            创建UIApplication对象并设置它的代理
            会开启一个运行循环,主循环,保证程序不退出,并处理事件
            加载info.plist文件,查看是否指定main.
                指定main了会先创建一个UIWindow,并指定main.storyBoard文件中箭头指向的控制器为根控制器
                把main.storyBoard文件中箭头指向的控制器view添加到UIWindow上显示出来
            通知应用程序代理,应用程序启动完毕


【录播】UIWindow(27分钟)

    UIWindow
        程序启动完毕后创建的第一个视图控件
        接着创建控制器的view
        接着将控制器的view添加到UIWindow上,于是控制器的view就显示在了屏幕上


    没有UIWindow就看不到任何界面
        创建窗口
        设置窗口的根控制器
        显示窗口


    makeKeyAndVisible的作用
        设置当前window为主window
            [UIApplication sharedApplication].keyWindow = self.window;
        显示窗口
            self.window.hidden = NO;
            [self.window addsubView:rootViewController.view]



【录播】UIWindow补充(15分钟)
    键盘是一个UIWindow对象

    状态栏也是一个UIWindow对象

    UIWindow对象是有级别的
        UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert


【录播】initWithNibName原理(11分钟)
    1.指定名称,会加载指定名称的xib
    2.如果name指定的是nil
        先去加载相同名称:LoginViewController.xib
        如果没有再去加载去掉Controller的文件,LoginView.xib
    3.如果还没有,就不使用xib,就创建一个空白的view


【录播 M】loadView方法(23分钟)     
    作用:创建控制器的view
    什么时候调用:每一次使用控制器view的时候调用
    内部做了什么事:
        1.是否从storyboard加载view
            self.view = storyboard中的view
        2.是否从xib文件加载
            self.view = xib文件中的view
        3.如果都不是
            self.view = [[UIView alloc] init];

    一旦重写了loadView,只能自己创建view,[super loadView]也不管用



【录播 M】loadView方法(补充)(8分钟)  
    view的加载过程
        -(UIView*)view{
            if (_view == nil){
                [self loadView];
                [self viewDidLoad]
            }
            retur _view;
        }

05 iOS大神班-UI进阶-第三章(上)

【录播】控制器View的生命周期(28分钟)

    视图的声明周期
        loadView
        viewDidLoad
        viewWillAppear
        viewWillLayoutSubViews
        viewDidLayoutSubViews
        viewDidAppear
        viewWillDisappear
        viewWillLayoutSubViews
        viewDidLayoutSubViews
        viewDidDisappear
        viewWillUnload
        viewDidUnload




    viewWill/DidLayoutSubViews调用时机
        view自己被添加到父view上时
        view布局自己的子view时
        当屏幕打横时
        当view自己的尺寸发生变化时
        当view消失的时候会调用

07 iOS大神班-UI进阶-第四章(上)

【录播】应用程序沙盒简介(20分钟)
    存储数据的方式
        XML属性列表,(plist)归档
        Preference(偏好设置)
        NSKeyedArchiver归档(NSCoding)
        SQLite3
        Core Data

    沙盒目录结构
        Layer:应用程序的包
        Document
            应用程序运行时需要持久化的数据
            iTunes同步设备时会备份该目录
            不允许存放大文件

        Library
            Caches
                应用程序运行时需要持久化的数据
                iTunes同步设备时不会备份该目录
                存放大文件

            Preference
                保存应用的偏好设置
                应用程序的setting设置保存在该目录
                iTunes同步设备时会备份该目录


        tmp
            应用程序运行时需要的临时数据,使用完毕时将文件从该目录清除
            应用没有运行时,系统可能会清除该目录下的文件
            iTunes同步设备时不会备份该目录



【录播】plist存存储(22分钟)
    获取Documents目录
    数组写入array.plist文件,从array.plist文件获取
    字典写入dic.plist文件,从dic.plist文件获取


【录播】偏好设置(掌握)(11分钟)

    偏好设置
        不用关心路径,自动保存到Library/Preference/xxx.plist文件内
    
    存数据
        NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];
        [userDefault setObject:@"" forKey:@""];
        [userDefault synchronize];//iOS7之后不需要写这个了

    取数据
        [userDefault objectForKey:@""];
        [userDefault integerForKey:@""];
        [userDefault boolForKey:@""];





【录播】通讯录(存储用户名,密码)(17分钟)
    userdefault 保存用户名密码


【录播】归档(基本使用)(25分钟)
    自定义对象无法直接保存
    归档
    解档

【录播】initWithCoder(20分钟)

    NSCoding协议
        解档,归档时会调用

    xib,初始化时会调用

10 iOS大神班-UI进阶-第五章(上)

【录播】transform(22分钟)
    平移,旋转,缩放
    不要叠加使用,有其它方法办到



【录播】事件处理简介(14分钟)
    事件类型
        触摸事件
            有对应的代理方法
        加速计事件
            有对应的代理方法
        远程控制事件
            有对应的代理方法

    响应者对象
        继承了UIResponder对象的类
        UIApplication
        UIViewController
        UIView



【录播】UIView的拖拽(26分钟)

    UITouch对象
        触摸的位置,时间,阶段
        手指移动时会实时更新同一个对象
        手指离开时,销毁对象



【录播】事件传递(10分钟)
    发生触摸事件后,系统会将事件放入一个由UIApplication管理的事件队列

    顺序
        UIApplication会将事件先发送给主window
        主window找到合适的视图控件后,调用控件的touches方法,来处理事件
        事件传递是从父控件到子控件的过程
        父控件不能接收触摸事件,子控件就不能接收触摸事件

    不接受触摸事件的三种情况
        关闭了用户交互
        隐藏了控件
        透明度 < 0.01


【录播】hitTest方法练习1(12分钟)
    如何找到最适合的view
        自己是否能接收触摸事件
        触点是否落在自己身上
        从后往前遍历子控件,重复上边两个步骤




【录播】HitTest方法(15分钟)
    当事件传递给当前view时会调用view的hitTest方法
    作用:返回最适合的view
    返回谁,谁就是最适合的view,谁就调用自己的touches方法

【录播】pointInside方法(16分钟)
    判断点在不在自己身上
        调用pointInside方法
        

总结:

//LCBaseView的hitTest方法
-[LCBaseView isUserInteractionEnabled]
-[LCBaseView pointInside:withEvent:]

//子view1
-[LCBaseLabel isUserInteractionEnabled]
-[LCBaseLabel pointInside:withEvent:]

//子view2
-[LCBaseLabel hitTest:withEvent:]
-[LCBaseView hitTest:withEvent:]


当事件传递给当前view时会调用view的hitTest方法

hitTest:withEvent:方法内部的调用逻辑如下:
    1. 调用isUserInteractionEnabled
        否:返回nil;
        是:进行步骤2

    2. 调用pointInside:withEvent:
        否:返回nil
        是:进行步骤3

    3.从后往前遍历子view,调用子View的hitTest:withEvent:的方法,子view重复上述步骤
        子view1:hitTest
            3-1.是否开启了用用户交互
                否:返回nil
                是:调用步骤3-2
            3-2.是否落在自身
                否:返回nil
                是:进行步骤3-3
            3-3.是否还有子view
                是:重复
                否:返回自身

11 iOS大神班-UI进阶-第五章(下)

【录播】事件响应(响应者链条)(24分钟)
    介绍
        响应者链条:是由多个响应者对象连接起来的链条
        作用:能很清楚的看见每个响应者之间的联系,并且可以让一个事件多个对象处理。
        响应者对象:能处理事件的对象

    链条
        subView -> View -> (ViewController) -> KeyWindow -> UIApplication

    事件
        touches
        [super touches]
        [super touches] 是从父类开始调用,并不是调用父view的touches方法
        [super touches] 而是其内部会找到父view,调用父view的toches方法

17 iOS大神班-UI进阶-第八章(上)

【录播】CALayer基本操作(23分钟)
    CALayer的作用
        当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,
        并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示
        UIView的显示是因为有图层

    基本使用
        阴影,圆角,边框
        还可以添加动画
    

    属性
        CGRect bounds;
        CGPoint position;
        CGPoint anchorPoint;
        CGColorRef backgroundColor;
        CATransform3D transform;




【录播】CATransform3D(20分钟)
        CATransform3DMakeTranslation (CGFloat tx,CGFloat ty, CGFloat tz)
        CATransform3DTranslate (CATransform3D t, CGFloat tx,CGFloat ty, CGFloat tz)



【录播】UIView和CALayer的选择(12分钟)
    有用户交互的用UIView
    没有用户交互的用CALayer



【录播】position和anchorPoint(12分钟)
    
    @property CGPoint position;
        用来设置CALayer在父层中的位置
        以父层的左上角为原点(0, 0)

    @property CGPoint anchorPoint;
        称为“定位点”、“锚点”
        决定着CALayer身上的哪个点会在position属性所指的位置
        以自己的左上角为原点(0, 0)
        它的x、y取值范围都是0~1,默认值为(0.5, 0.5)


【录播】position和anchorPoint代码演示(12分钟)
    layer.position = CGPointMake(100, 100);
    layer.anchorPoint = CGPointMake(0.5, 0.5);



【录播】隐式动画(9分钟)
    介绍
        每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)
        所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画
        当对非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果

    列举几个常见的Animatable Properties:
        bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画
        backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画
        position:用于设置CALayer的位置。修改这个属性会产生平移动画

    可以通过动画事务(CATransaction)关闭默认的隐式动画效果
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        self.myview.layer.position = CGPointMake(10, 10);
        [CATransaction commit];



【录播】时钟(搭建界面)(19分钟)
    旋转,缩放,平移,都是针对锚点进行的



【录播】时钟(旋转时, 分,秒)(21分钟)

18 iOS大神班-UI进阶-第八章(下)

【录播】CABasicAnimation(20分钟)
    继承关系
        CAAnimation
            CAAnimationGroup
            CAPropertyAnimation
                CABasicAnimation
                CAKeyframeAnimation
            CATransition


     CABasicAnimation

        创建动画
            //1.创建动画对象
            CABasicAnimation *anim  = [CABasicAnimation animation];

        设置动画属性
            //2.设置动画属性.
            anim.keyPath = @"position.y";
            anim.toValue = @(400);
            //动画完成时会自动删除动画
            anim.removedOnCompletion = NO;
            //动画完成时保持什么状态
            anim.fillMode = kCAFillModeForwards;

        添加动画
            [self.redView.layer addAnimation:anim forKey:@"anim1"];


【录播】心跳效果(8分钟)

    创建动画对象
        CABasicAnimation *anim = [CABasicAnimation animation];

    设置动画属性
        //设置动画属性
        anim.keyPath = @"transform.scale";
        anim.toValue = @0;
        //设置执行次数
        anim.repeatCount = HUGE;
        anim.duration = 0.5;
        //自动返转(怎么去,怎么回来)
        anim.autoreverses = YES;
    
    添加动画
        [self.imageView.layer addAnimation:anim forKey:@"scaleAnim"];


【录播】帧动画(图片抖动)(11分钟)

    创建动画对象
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

    设置动画属性
        anim.keyPath = @"transform.rotation";
        //进行多个值之间的动画
        anim.values = @[@(angleToRadio(-5)),@(angleToRadio(5)),@(angleToRadio(-5))];
        anim.repeatCount = MAXFLOAT;
        //anim.autoreverses = YES;
        anim.duration = 0.1;
    
    添加动画
        [self.iconImageView.layer addAnimation:anim forKey:nil];


【录播】帧动画(根据路径做动画)(13分钟)

    创建动画对象
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

    设置动画属性
        anim.keyPath = @"position";
        //设置路径
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(100, 288)];
        [path addLineToPoint:CGPointMake(100, 100)];
        [path addLineToPoint:CGPointMake(300, 100)];
        [path addQuadCurveToPoint:CGPointMake(300, 600) controlPoint:CGPointMake(400, 600)];
        [path addLineToPoint:CGPointMake(100, 288)];
        anim.path = path.CGPath;
        anim.duration = 5.0;
        anim.repeatCount = HUGE;
        //根据路径,自动旋转
        anim.rotationMode = @"autoReverse";
        //设置时间计算模型
        anim.calculationMode = @"cubic";
    
    添加动画
        [self.fistLayer addAnimation:anim forKey:@"moveAnim"];




【录播】转场动画(16分钟)

    转场代码
        //转场代码必须得要与转场动画在同一个方法当中.
        _imageIndex++;
        if (_imageIndex == 5) {
            _imageIndex = 0;
        }
        
        NSString *imageName = [NSString stringWithFormat:@"%d",_imageIndex];
        self.imageV.image = [UIImage imageNamed:imageName];
    
    转场动画
        //添加动画
        CATransition *anim = [CATransition animation];
        //转场类型
        anim.type = @"pageCurl";
        //设置方向
        anim.subtype = @"fromTop";
        
        //从哪个位置开始动画
        anim.startProgress = 0.2;
        anim.endProgress = 0.5;
        anim.duration = 1.0;
    
    添加动画
        [self.imageV.layer addAnimation:anim forKey:nil];


【录播】动画组(7分钟)

    CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
    groupAnim.animations = @[anim, anim2];;
    //把数组当中的所有动画给添加到layer
    groupAnim.removedOnCompletion = NO;
    groupAnim.duration = 1.0;
    groupAnim.fillMode  = kCAFillModeForwards;
    [self.redView.layer addAnimation:groupAnim forKey:nil];



【录播】UIView与核心动画区别(12分钟)
    UIView与核心动画区别?
        1.核心动画只作用在layer上
        2.核心动画看到一切都是假像.并没有去修改属性的真实值.
 
    什么时候使用核心动画什么时候使用UIView动画
        当需要与用户进行交互时,必须得要使用UIView动画
        做帧动画时 当根据路径做动画时,使用核心动画
        做转场动画时,使用核心动画,转场类型比较多.




【录播】转盘(界面搭建,旋转)(22分钟)

    封装一个WheelView

    开始旋转
        - (void)start {
            CABasicAnimation *anim = [CABasicAnimation animation];
            anim.keyPath = @"transform.rotation";
            anim.toValue = @(M_PI * 2);
            anim.repeatCount = HUGE;
            anim.duration = 3.0;
            [self.contentImageView.layer addAnimation:anim forKey:nil];
        }



【录播】转盘(添加按钮)(20分钟)
    btn.layer.anchorPoint = CGPointMake(0.5, 1);
    btn.layer.position = CGPointMake(self.contentImageView.bounds.size.width * 0.5, self.contentImageView.bounds.size.height * 0.5);
    btn.transform = CGAffineTransformMakeRotation(angle * M_PI / 180.0);

19 iOS大神班-UI进阶-第九章(上)

【录播】转盘(解决按钮重叠)(6分钟)
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        CGRect rect = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height * 0.5);
        //给定一个区域,如果点在此区域当中 ,能够点击,
        if (CGRectContainsPoint(rect, point)) {
            return [super hitTest:point withEvent:event];
        }else {
            //否则不能点击
            return nil;
        }
    }

26 iOS大神班-网络多线程-第一章(中)

【录播】原子和非原子属性(18分钟)
    介绍
        OC在定义属性时有nonatomic和atomic两种选择
        atomic:原子属性,为setter方法加锁(默认就是atomic)
        nonatomic:非原子属性,不会为setter方法加锁

    nonatomic和atomic对比
        atomic:线程安全,需要消耗大量的资源
        nonatomic:非线程安全,适合内存小的移动设备

    iOS开发的建议
        所有属性都声明为nonatomic
        尽量避免多线程抢夺同一块资源
        尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.