前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Core Animation实战三(图层几何学)

Core Animation实战三(图层几何学)

作者头像
星宇大前端
发布2019-01-15 15:12:41
3990
发布2019-01-15 15:12:41
举报
文章被收录于专栏:大宇笔记大宇笔记

锚点

了解游戏的人一般都知道锚点,在UIView中我们很少用到。anchorPoint位于图层的中点,所以图层的将会以这个点为中心放置。anchorPoint属性并没有被UIView接口暴露出来,这也是视图的position属性被叫做“center”的原因。但是图层的anchorPoint可以被移动,比如你可以把它置于图层frame的左上角,于是图层的内容将会向右下角的position方向移动(图3.3),而不是居中了。

Demo:

主要是看下指针的位置

Xib指针位置如图(锚点在中心位置):

最后效果如下:

Demo代码:

代码语言:javascript
复制
//
//  ClockViewController.m
//  LayerStudyDemo
//
//  Created by apple on 2017/9/25.
//  Copyright © 2017年 ZY. All rights reserved.
//

#import "ClockViewController.h"

@interface ClockViewController ()
@property (weak, nonatomic) IBOutlet UILabel *hourLabel;
@property (weak, nonatomic) IBOutlet UILabel *minuteLabel;
@property (weak, nonatomic) IBOutlet UILabel *secondLabel;
@property (nonatomic, weak) NSTimer *timer;
@end

@implementation ClockViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(showTime) userInfo:nil repeats:YES];
}

-(void)showTime{
    NSCalendar  * calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierChinese];
    NSUInteger units = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
    CGFloat hoursAngle = (components.hour / 12.0) * M_PI * 2.0;
    //calculate hour hand angle //calculate minute hand angle
    CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0;
    //calculate second hand angle
    CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0;
    
    //设置锚点
    self.hourLabel.layer.anchorPoint =self.minuteLabel.layer.anchorPoint =self.secondLabel.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
    
    //rotate hands
    self.hourLabel.transform = CGAffineTransformMakeRotation(hoursAngle);
    self.minuteLabel.transform = CGAffineTransformMakeRotation(minsAngle);
    self.secondLabel.transform = CGAffineTransformMakeRotation(secsAngle);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

坐标系和Hit Testing

CALayer并不关心任何响应链事件,所以不能直接处理触摸事件或者手势。但是它有一系列的方法帮你处理事件:-containsPoint:-hitTest:

-containsPoint:接受一个在本图层坐标系下的CGPoint,如果这个点在图层frame范围内就返回YES

-hitTest:方法同样接受一个CGPoint类型参数,而不是BOOL类型,它返回图层本身,或者包含这个坐标点的叶子节点图层。这意味着不再需要像使用-containsPoint:那样,人工地在每个子图层变换或者测试点击的坐标。如果这个点在最外面图层的范围之外,则返回nil。

代码语言:javascript
复制
//
//  HitTestingViewController.m
//  LayerStudyDemo
//
//  Created by apple on 2017/9/25.
//  Copyright © 2017年 ZY. All rights reserved.
//

#import "HitTestingViewController.h"

@interface HitTestingViewController ()
@property (weak, nonatomic) IBOutlet UIView *wildView;
@property (nonatomic, strong) CALayer *innerLayer;
@end

@implementation HitTestingViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self creatInnerLayer];
}

-(void)creatInnerLayer{
    self.innerLayer = [CALayer layer];
    self.innerLayer.frame = CGRectMake((self.wildView.frame.size.width-100)/2, (self.wildView.frame.size.height-100)/2, 100.0f, 100.0f);
    self.innerLayer.backgroundColor = [UIColor blueColor].CGColor;
    //add it to our view
    [self.wildView.layer addSublayer:self.innerLayer];
}

// containsPoint 判断较麻烦,需要把坐标转换图层成每个坐标系下的坐标
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    CGPoint point  =  [[touches anyObject] locationInView:self.view];
    //将点击的点从以 self.view.layer 为父类的坐标系转到self.wildView.layer为父类的坐标系
    point = [self.wildView.layer convertPoint:point fromLayer:self.view.layer];
    if ([self.wildView.layer containsPoint:point]) {
        //convert point to blueLayer’s coordinates
        point = [self.innerLayer convertPoint:point fromLayer:self.wildView.layer];
        if ([self.innerLayer containsPoint:point]) {
            [[[UIAlertView alloc] initWithTitle:@"Inside innerLayer Layer"
                                        message:nil
                                       delegate:nil
                              cancelButtonTitle:@"OK"
                              otherButtonTitles:nil] show];
        } else {
            [[[UIAlertView alloc] initWithTitle:@"Inside wildView Layer"
                                        message:nil
                                       delegate:nil
                              cancelButtonTitle:@"OK"
                              otherButtonTitles:nil] show];
        }
    }
    
}
 

//-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//
//    CGPoint point  =  [[touches anyObject] locationInView:self.view];
//    //返回点击layer
//    CALayer * hitLayer = [self.wildView.layer hitTest:point];
//    if (hitLayer==self.innerLayer) {
//
//            [[[UIAlertView alloc] initWithTitle:@"Inside innerLayer Layer"
//                                        message:nil
//                                       delegate:nil
//                              cancelButtonTitle:@"OK"
//                              otherButtonTitles:nil] show];
//    } else if(hitLayer==self.wildView.layer){
//            [[[UIAlertView alloc] initWithTitle:@"Inside wildView Layer"
//                                        message:nil
//                                       delegate:nil
//                              cancelButtonTitle:@"OK"
//                              otherButtonTitles:nil] show];
//    }else{
//        [[[UIAlertView alloc] initWithTitle:@"Inside  View"
//                                    message:nil
//                                   delegate:nil
//                          cancelButtonTitle:@"OK"
//                          otherButtonTitles:nil] show];
//    }
//}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



@end

DEMO地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年10月30日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 锚点
  • 坐标系和Hit Testing
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档