UI进阶

第一课

1UIApplication

15121246699537.jpg

2.PCH的配置

15121249209730.jpg

3.注册推送

以下分别是 iOS 10 之前和之后的注册方式,其中的 UNAuthorizationOptions 里还可以找到 1 个 UNAuthorizationOptionCarPlay 的值是专为车载系统定制的值。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //iOS 10 before
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [application registerUserNotificationSettings:settings];

    //iOS 10
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (!error) {
            NSLog(@"request authorization succeeded!");
        }
    }];

    return YES;
}

作者:pikacode
链接://www.greatytc.com/p/2f3202b5e758
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.UIWindows

  • 在程序当中,状态栏和键盘,它都属性是 个窗 .可以通过打印的 式来验证. 设置window的层级.UIWindowLevelNormal它是 个CGFloat类型. self.window.windowLevel = UIWindowLevelNormal UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert

5.从Storyboard加载控制器

15123761360920.jpg

第二课

15124028675903.jpg

15124028927003.jpg

第三课

1.segue的底层实现

![15124762493040.jpg](http://upload-images.jianshu.io/upload_images/10921965-1744fef944a93417.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.通知

当控制器销毁是记得移除通知

第四课

1.个人详情页代码

- (void)viewDidLoad {
    [super viewDidLoad];

    
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    
    
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
    
    //NSLog(@"%@",NSStringFromCGRect(self.tableView.frame));
    
    //1.凡是在导航条下面的scrollView.默认会设置偏移量.UIEdgeInsetsMake(64, 0, 0, 0)
    //self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
    
    //不要自动设置偏移量
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    //让导航条隐藏
    //self.navigationController.navigationBar.hidden = YES;
    
    //导航条或者是导航条上的控件设置透明度是没有效果.
    //self.navigationController.navigationBar.alpha = 0;
    
    //设置导航条背景(必须得要使用默认的模式UIBarMetricsDefault)
    //当背景图片设置为Nil,系统会自动生成一张半透明的图片,设置为导航条背景
    
    [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
    
    [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
    
    //当调用contentInset会自动调用scrollViewDidScroll
    self.tableView.contentInset = UIEdgeInsetsMake(244, 0, 0, 0);
    
    //设置标题
    UILabel *title = [[UILabel alloc] init];
    title.text = @"个人详情页";
    [title sizeToFit];
    title.textColor = [UIColor colorWithWhite:0 alpha:0];
    
    self.navigationItem.titleView = title;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
    //求偏移量
    //当前点 - 最原始的点
    NSLog(@"%f",scrollView.contentOffset.y);
    CGFloat offset = scrollView.contentOffset.y - oriOfftY;
    NSLog(@"offset======%f",offset);
    
    CGFloat h = oriHeight - offset;
    if (h < 64) {
        h = 64;
    }
    self.heightConstr.constant = h;
    
   
    //根据透明度来生成图片
    //找最大值/
    CGFloat alpha = offset * 1 / 136.0;
    if (alpha >= 1) {
        alpha = 0.99;
    }
    
    //拿到标题
    UILabel *titleL = (UILabel *)self.navigationItem.titleView;
    titleL.textColor = [UIColor colorWithWhite:0 alpha:alpha];
    
    //把颜色生成图片
    UIColor *alphaColor = [UIColor colorWithWhite:1 alpha:alpha];
    //把颜色生成图片
    UIImage *alphaImage = [UIImage imageWithColor:alphaColor];
    //修改导航条背景图片
    [self.navigationController.navigationBar setBackgroundImage:alphaImage forBarMetrics:UIBarMetricsDefault];
    

    
    
    
}

2.归档

15126589415829.jpg
15126589471912.jpg

第五课

1.事件传递

  • 1.当一个控件如果它的父控件不能够接收事件,那么它里面子控件也是不能接收事件的
  • 2.当一个控件隐藏的时候,它里面的子控件也跟着隐藏
  • 3.当一个控件透明的时候,它里面的子控件也跟着透明

模拟系统的hitText方法

//作用:去寻找最适合的View
//什么时候调用:当一个事件传递给当前View,就会调用.
//返回值:返回的是谁,谁就是最适合的View(就会调用最适合的View的touch方法)
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
   
    //1.判断自己能否接收事件
    if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) {
        return nil;
    }
    //2.判断当前点在不在当前View.
    if (![self pointInside:point withEvent:event]) {
        return nil;
    }
    //3.从后往前遍历自己的子控件.让子控件重复前两步操作,(把事件传递给,让子控件调用hitTest)
    int count = (int)self.subviews.count;
    for (int i = count - 1; i >= 0; i--) {
        //取出每一个子控件
        UIView *chileV =  self.subviews[i];
        //把当前的点转换成子控件从标系上的点.
        CGPoint childP = [self convertPoint:point toView:chileV];
        UIView *fitView = [chileV hitTest:childP withEvent:event];
        //判断有没有找到最适合的View
        if(fitView){
            return fitView;
        }
    }
    
    //4.没有找到比它自己更适合的View.那么它自己就是最适合的View
    return self;
    
}



//作用:判断当前点在不在它调用View,(谁调用pointInside,这个View就是谁)
//什么时候调用:它是在hitTest方法当中调用的.
//注意:point点必须得要跟它方法调用者在同一个坐标系里面
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    NSLog(@"%s",__func__);
    return YES;
}

15128269778909.jpg
![[图片上传中...(15129827603014.jpg-7d8817-1520410012340-0)] ](http://upload-images.jianshu.io/upload_images/10921965-89b8d5168b2a4d00.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.抽屉效果

15129827509277.jpg
15129827603014.jpg

第六课

1.定时器

1. 先要了解setNeedsDisplay
setNeedsDisplay底层会调 DrawRect 法重绘. 但是它不是  就进 重绘.它仅仅是设置了 个重绘标志,等到下 次屏幕刷新的时候才会 调 DrawRect 法.
如果使 NSTime的话,假设是0.01调  次重绘.假设屏幕0.02秒的时候它才刷新 次. 中间就会等0.01秒.
也就是每次都会等0.01秒这样累加上去.让变的越来越卡顿.
使 CADisplayLink时,它的定时器 法就是屏幕每次刷新的时候就会调 (通常屏幕 秒 钟刷新60次) 它和setNeedsDisplay调 DrawRect 法的时机正好吻合,不会出间等待间隔.不会出现 屏幕卡顿现象.
2.2如何使 CADisplayLink添加定时器?
Target:哪个对象要监听 法.
selector:监听的 法名称.
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)]; 想要让CADisplayLink 作,必须得要把它添加到主运 循环. 只要添加到主运 循环, 跟模式没有关系
[link addToRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];

2.NSAttributedString描述

字符属性

字符属性可以应用于 attributed string 的文本中。

NSString *const NSFontAttributeName;(字体)

NSString *const NSParagraphStyleAttributeName;(段落)

NSString *const NSForegroundColorAttributeName;(字体颜色)

NSString *const NSBackgroundColorAttributeName;(字体背景色)

NSString *const NSLigatureAttributeName;(连字符)

NSString *const NSKernAttributeName;(字间距)

NSString *const NSStrikethroughStyleAttributeName;(删除线)

NSString *const NSUnderlineStyleAttributeName;(下划线)

NSString *const NSStrokeColorAttributeName;(边线颜色)

NSString *const NSStrokeWidthAttributeName;(边线宽度)

NSString *const NSShadowAttributeName;(阴影)(横竖排版)

NSString *const NSVerticalGlyphFormAttributeName;

常量

1> NSFontAttributeName(字体)

该属性所对应的值是一个 UIFont 对象。该属性用于改变一段文本的字体。如果不指定该属性,则默认为12-point Helvetica(Neue)。

2> NSParagraphStyleAttributeName(段落)

该属性所对应的值是一个 NSParagraphStyle 对象。该属性在一段文本上应用多个属性。如果不指定该属性,则默认为 NSParagraphStyle 的defaultParagraphStyle 方法返回的默认段落属性。

3> NSForegroundColorAttributeName(字体颜色)

该属性所对应的值是一个 UIColor 对象。该属性用于指定一段文本的字体颜色。如果不指定该属性,则默认为黑色。

4> NSBackgroundColorAttributeName(字体背景色)

该属性所对应的值是一个 UIColor 对象。该属性用于指定一段文本的背景颜色。如果不指定该属性,则默认无背景色。

5> NSLigatureAttributeName(连字符)

该属性所对应的值是一个 NSNumber 对象(整数)。连体字符是指某些连在一起的字符,它们采用单个的图元符号。0 表示没有连体字符。1 表示使用默认的连体字符。2表示使用所有连体符号。默认值为 1(注意,iOS 不支持值为 2)。

6> NSKernAttributeName(字间距)

该属性所对应的值是一个 NSNumber 对象(整数)。字母紧排指定了用于调整字距的像素点数。字母紧排的效果依赖于字体。值为 0 表示不使用字母紧排。默认值为0。

7> NSStrikethroughStyleAttributeName(删除线)

该属性所对应的值是一个 NSNumber 对象(整数)。该值指定是否在文字上加上删除线,该值参考“Underline Style Attributes”。默认值是NSUnderlineStyleNone。

8> NSUnderlineStyleAttributeName(下划线)

该属性所对应的值是一个 NSNumber 对象(整数)。该值指定是否在文字上加上下划线,该值参考“Underline Style Attributes”。默认值是NSUnderlineStyleNone。

9> NSStrokeColorAttributeName(边线颜色)

该属性所对应的值是一个 UIColor 对象。如果该属性不指定(默认),则等同于 NSForegroundColorAttributeName。否则,指定为删除线或下划线颜色。更多细节见“Drawing attributedstrings that are both filled and stroked”。

10> NSStrokeWidthAttributeName(边线宽度)

该属性所对应的值是一个 NSNumber 对象(小数)。该值改变描边宽度(相对于字体size 的百分比)。默认为 0,即不改变。正数只改变描边宽度。负数同时改变文字的描边和填充宽度。例如,对于常见的空心字,这个值通常为3.0。

11> NSShadowAttributeName(阴影)

该属性所对应的值是一个 NSShadow 对象。默认为 nil。

12> NSVerticalGlyphFormAttributeName(横竖排版)

该属性所对应的值是一个 NSNumber 对象(整数)。0 表示横排文本。1 表示竖排文本。在 iOS 中,总是使用横排文本,0 以外的值都未定义。

第八课

1.CALayer的基本操作

  • 设置阴影
    • 默认图层是有阴影的, 只不过,是透明的
      _RedView.layer.shadowOpacity = 1;
  • 设置图片的圆角半径
        _imageView.layer.cornerRadius = 50;
        裁剪,超出裁剪区域的部分全部裁剪掉
        _imageView.layer.masksToBounds = YES;
        注意:UIImageView当中Image并不是直接添加在层上面的.这是添加在layer当中的contents里.
        我们设置层的所有属性它只作用在层上面.对contents里面的东西并不起作用.所以我们看不到图片有圆角的效果.
        想要让图片有圆角的效果.可以把masksToBounds这个属性设为YES,
        当设为YES,把就会把超过根层以外的东西都给裁剪掉.
  • layer的 CATransform3D属性.
 只有旋转的时候才可以看出3D的效果.
      旋转
      x,y,z 分别代表x,y,z轴.
      CATransform3DMakeRotation(M_PI, 1, 0, 0);
      平移
      CATransform3DMakeTranslation(x,y,z)
      缩放
      CATransform3DMakeScale(x,y,z);
      
      可以通过KVC的方式进行设置属性.
      但是CATransform3DMakeRotation它的值,是一个结构体, 所以要把结构转成对象.
      NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)];
      [_imageView.layer setValue:value forKeyPath:@"transform.scale"];

  可以通过KVC的方式进行设置属性.
  但是CATransform3DMakeRotation它的值,是一个结构体, 所以要把结构转成对象.
  NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)];
  [_imageView.layer setValue:value forKeyPath:@"transform.scale"];

2.关于CALayer的疑惑?

  为什么要使用CGImageRef、CGColorRef?
  为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef
  
  UIView和CALayer都能够显示东西,该怎样选择?
  对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以
  如果显示出来的东西需要跟用户进行交互的话,用UIView;
  如果不需要跟用户进行交互,用UIView或者CALayer都可以
  CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级

3.隐式动画

如何取消隐式动画?
    首先要了解动画底层是怎么做的.动画的底层是包装成一个事务来进行的.
    什么是事务?
    很多操作绑定在一起,当这些操作执行完毕后,才去执行下一个操作.
    
    开启事务
    [CATransaction begin];
    设置事务没有动画
    [CATransaction setDisableActions:YES];
    设置动画执行的时长
    [CATransaction setAnimationDuration:2];
    
    
    提交事务
    [CATransaction commit];

核心动画

15132255337759.jpg

1.CABasicAnimation基础核心动画

         
    CABasicAnimation *anim =[CABasicAnimation  animation];
    设置缩放属性
    anim.keyPath = @"transform.scale";
    缩放到最小
    anim.toValue = @0;
    设置动画执行的次数
    anim.repeatCount = MAXFLOAT;
    设置动画执行的时长
    anim.duration = 0.25;
    设置动画自动反转(怎么去, 怎么回)
    anim.autoreverses = YES;
    添加动画
    [self.heartView.layer addAnimation:anim forKey:nil];

2.图片抖动(帧动画)CAKeyframeAnimation

1.帧动画介绍:
        CAKeyframeAnimation它可以在多个值之间进行动画.
        设置多值之间的属性为:
        后面是一个数组,就是要设置的多个值.
        anim.values = @[];
        
        它还可以根据一个路径做动画.
        anim.path = 自己创建的路径.
    
    2.图片抖动思路:
        其实就是做一个左右旋转的动画.先让它往左边旋转-5,再往右边旋转5度,再从5度旋转到-5度.
        就会有左右摇摆的效果了.
        
        具体实现代码
        创建帧动画
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        设置动画属性为旋转
        anim.keyPath = @"transform.rotation";
        设置属性值为多个属性
        anim.values = @[@(angle2radio(-5)),@(angle2radio(5)),@(angle2radio(-5))];
        设置动画执行次数
        anim.repeatCount = MAXFLOAT;
        添加动画
        [_imageView.layer addAnimation:anim forKey:nil];
    
    3.根据圆形的路径做移动的效果.
        创建路径
        UIBezierPath *path = [UIBezierPath 
                              bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 100)];
       [path addLineToPoint:CGPointMake(200, 500)];
       
       把路径设为动画的属性
       anim.path = path.CGPath;

3.转场动画CATransition

09-转场动画
    
    1.什么是转场动画?
        就是从一个场景转换到另一个场景,像导航控制器的push效果,就是一个转场.
    
    2.如何创建转场动画
      创建转场动画
      CATransition *anim = [CATransition animation];
      设置转场类型
      anim.type = @"cube";
      anim.duration = 1;
      设置转场的方向
      anim.subtype = kCATransitionFromLeft;
      设置动画的开始位置
      anim.startProgress = 0.5;
      设置动画的结束位置
      anim.endProgress  =0.8;
      添加动画.了
     [_imageV.layer addAnimation:anim forKey:nil];


     要执行动画的代码称为转场代码.
     转场动画要和转场代码写在同一个方法当中才有动画效果.
     
    3.UIView进行转场动画
        
       [UIView transitionWithView:self.imageV duration:1 
        options:UIViewAnimationOptionTransitionFlipFromRight 
        animations:^{
            转场代码
        } completion:^(BOOL finished) {
            动画执行完毕时调用.
        }];
        
        使用UIView转场的类型比较少.

4.动画组CAAnimationGroup


    
    可以同时执行多个动画.
    创建组动画
    CAAnimationGroup *group = [CAAnimationGroup animation];
    
    平移
    CABasicAnimation *anim = [CABasicAnimation animation];
    anim.keyPath = @"position.y";
    anim.toValue = @400;
    
    缩放
    CABasicAnimation *scaleAnim = [CABasicAnimation  animation];
    scaleAnim.keyPath = @"transform.scale";
    scaleAnim.toValue = @0.5;
    设置动画组属性
    group.animations = @[anim,scaleAnim];
    
    group.removedOnCompletion = NO;
    group.fillMode = kCAFillModeForwards;
    添加组动画
    [self.redView.layer addAnimation:group forKey:nil];
    
    使用动画组的好处,不需要每次都去添加动画,设置动画完成时的属性.
    只需要把要执行的动画,添加到动画组的animations数组当中即可,
    最后把组动画添加到层上面,就会自动执行数组当中的动画.
    动画完成时设置的属性也只需要设置一次.

5.UIView与核心动画对比?

1.UIView和核心动画区别?
   核心动画只能添加到CALayer
   核心动画一切都是假象,并不会改变真实的值。
   
2.什么时候使用UIView的动画?
  如果需要与用户交互就使用UIView的动画.
  不需要与用户交互可以使用核心动画
 
3.什么场景使用核心动画最多?
  在转场动画中,核心动画的类型比较多
  根据一个路径做动画,只能用核心动画(帧动画)
  动画组:同时做多个动画
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedA...
    SoManyDumb阅读 162评论 0 0
  • 核心动画 Core Animation简介 Core Animation,中文翻译为核心动画,它是一组非常强大的动...
    SoManyDumb阅读 196评论 0 0
  • Core Data Core Data框架提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在...
    SoManyDumb阅读 312评论 0 0
  • 残酷的时针飞快­ 关于你的音容笑貌模糊存在­ 仿佛高中记忆海底深埋­ 永远浮不上来­ 舍弃了一部分记忆童趣­ 我们...
    娱情饭桶说阅读 139评论 0 3
  • 鸟的自由在天空的高 鱼的自由在大海的深 马的自由在大地的广 人的自由在路的远方
    文刀之元阅读 415评论 0 1