初识CALayer之简易时钟





#import "ViewController.h" #import <QuartzCore/QuartzCore.h> @interface ViewController () { //时针 UIImageView *m_s; //分针 UIImageView *m_f; //秒针 UIImageView *m_m; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; m_s = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"s"]]; m_s.frame = CGRectMake(0, 0, 20, 90); m_f = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"f"]]; m_f.frame = CGRectMake(0, 0, 20, 100); m_m = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"m"]]; m_m.frame = CGRectMake(0, 0, 20, 130); CALayer *blueLayer = [[CALayer alloc] init]; blueLayer.frame = CGRectMake(10, 20, 300, 400); blueLayer.backgroundColor = [UIColor blueColor].CGColor; // 把blueLayer的contents属性设置成图片。 // contents /* An object providing the contents of the layer, typically a CGImageRef, * but may be something else. (For example, NSImage objects are * supported on Mac OS X 10.6 and later.) Default value is nil. * Animatable. *对象提供该层的内容,一个典型的cgimageref, *但可能是别的东西。(例如,nsimage对象 *后来支持在MAC OS X 10.6和默认值是零。)。 *动画。*/ UIImage *image = [UIImage imageNamed:@"b"]; blueLayer.contents = (__bridge id)(image.CGImage); /* CALayer与contentMode对应的属性叫做contentsGravity,但是它是一个NSString类型,而不是像对应的UIKit部分,那里面的值是枚举。contentsGravity可选的常量值有以下一些: kCAGravityCenter kCAGravityTop kCAGravityBottom kCAGravityLeft kCAGravityRight kCAGravityTopLeft kCAGravityTopRight kCAGravityBottomLeft kCAGravityBottomRight kCAGravityResize kCAGravityResizeAspect kCAGravityResizeAspectFill 和cotentMode一样,contentsGravity的目的是为了决定内容在图层的边界中怎么对齐,我们将使用kCAGravityResizeAspect,它的效果等同于UIViewContentModeScaleAspectFit, 同时它还能在图层中等比例拉伸以适应图层的边界。 */ blueLayer.contentsGravity = kCAGravityCenter; // 当用代码的方式来处理寄宿图的时候,一定要记住要手动的设置图层的contentsScale属性,否则,你的图片在Retina设备上就显示得不正确啦。代码如下: blueLayer.contentsScale = [UIScreen mainScreen].scale; // UIView有一个叫做clipsToBounds的属性可以用来决定是否显示超出边界的内容, //CALayer对应的属性叫做masksToBounds,把它设置为YES,图片就在边界里了 blueLayer.masksToBounds = YES; // [self addSpriteImage:image withContentRect:CGRectMake(0, 0, 1, 1) Layer:blueLayer]; // blueLayer.contentsCenter = CGRectMake(0.25, 0.25, .5, .5); // self.view.transform = CGAffineTransformMakeRotation(.5); [self.view.layer addSublayer:blueLayer]; m_s.center = CGPointMake(blueLayer.position.x , blueLayer.position.y); m_f.center = CGPointMake(blueLayer.position.x , blueLayer.position.y); m_m.center = CGPointMake(blueLayer.position.x , blueLayer.position.y); m_s.layer.anchorPoint = CGPointMake(.5, .9); m_f.layer.anchorPoint = CGPointMake(.5, .9); m_m.layer.anchorPoint = CGPointMake(.5, .9); [self.view addSubview:m_s]; [self.view addSubview:m_f]; [self.view addSubview:m_m]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES]; //set initial hand positions [self tick]; } - (void)tick { //convert time to hours, minutes and seconds NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit; 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; //rotate hands m_s.transform = CGAffineTransformMakeRotation(hoursAngle); m_f.transform = CGAffineTransformMakeRotation(minsAngle); m_m.transform = CGAffineTransformMakeRotation(secsAngle); } /*! * @Author Yunis_song, 15-01-07 16:01:51 * * @brief 加载图片切割尺寸,只加载自己想要的部分 * * @param image 图片 * @param rect 加载图片剪裁信息 * @param layer 图片加载到哪里 */ - (void)addSpriteImage:(UIImage *)image withContentRect:(CGRect)rect Layer:(CALayer *)layer //set image { layer.contents = (__bridge id)image.CGImage; //scale contents to fit layer.contentsGravity = kCAGravityResizeAspect; //set contentsRect //CGRectMake(x, y, w, h) 加载图片位置 //x 加载图片其实x坐标 值:0-1,相对位置 0 起始点 0.5 一半起始点 //y 加载图片其实y坐标 值:0-1,相对位置 0 起始点 0.5 一半起始点 //w 宽度 值:0-1 1加载全部 0.5 加载一般宽度 //h 高度 值:0-1 1加载全部 0.5 加载一般高度 layer.contentsRect = rect; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end

 

转载于:https://www.cnblogs.com/yunis/p/4210023.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为下列代码实现可暂停效果: import UIKit class ViewController: UIViewController { private let radarAnimation = "radarAnimation" private var animationLayer: CALayer? private var animationGroup: CAAnimationGroup? private var opBtn: UIButton! override func viewDidLoad() { super.viewDidLoad() let first = makeRadarAnimation(showRect: CGRect(x: 120, y: 100, width: 100, height: 100), isRound: true) view.layer.addSublayer(first) opBtn = UIButton(frame: CGRect(x: 100, y: 450, width: 80, height: 80)) opBtn.backgroundColor = UIColor.red opBtn.clipsToBounds = true opBtn.setTitle("Hsu", for: .normal) opBtn.layer.cornerRadius = 10 view.addSubview(opBtn) let second = makeRadarAnimation(showRect: opBtn.frame, isRound: false) view.layer.insertSublayer(second, below: opBtn.layer) } @IBAction func startAction(_ sender: UIButton) { animationLayer?.add(animationGroup!, forKey: radarAnimation) } @IBAction func stopAction(_ sender: UIButton) { animationLayer?.removeAnimation(forKey: radarAnimation) } private func makeRadarAnimation(showRect: CGRect, isRound: Bool) -> CALayer { // 1. 一个动态波 let shapeLayer = CAShapeLayer() shapeLayer.frame = showRect // showRect 最大内切圆 if isRound { shapeLayer.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: showRect.width, height: showRect.height)).cgPath } else { // 矩形 shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: showRect.width, height: showRect.height), cornerRadius: 10).cgPath } shapeLayer.fillColor = UIColor.orange.cgColor // 默认初始颜色透明度 shapeLayer.opacity = 0.0 animationLayer = shapeLayer // 2. 需要重复的动态波,即创建副本 let replicator = CAReplicatorLayer() replicator.frame = shapeLayer.bounds replicator.instanceCount = 4 replicator.instanceDelay = 1.0 replicator.addSublayer(shapeLayer) // 3. 创建动画组 let opacityAnimation = CABasicAnimation(keyPath: "opacity") opacityAnimation.fromValue = NSNumber(floatLiteral: 1.0) // 开始透明度 opacityAnimation.toValue = NSNumber(floatLiteral: 0) // 结束时透明底 let scaleAnimation = CABasicAnimation(keyPath: "transform") if isRound { scaleAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DScale(CATransform3DIdentity, 0, 0, 0)) // 缩放起始大小 } else { scaleAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DScale(CATransform3DIdentity, 1.0, 1.0, 0)) // 缩放起始大小 } scaleAnimation.toValue = NSValue.init(caTransform3D: CATransform3DScale(CATransform3DIdentity, 1.5, 1.5, 0)) // 缩放结束大小 let animationGroup = CAAnimationGroup() animationGroup.animations = [opacityAnimation, scaleAnimation] animationGroup.duration = 3.0 // 动画执行时间 animationGroup.repeatCount = HUGE // 最大重复 animationGroup.autoreverses = false self.animationGroup = animationGroup shapeLayer.add(animationGroup, forKey: radarAnimation) return replicator } }
06-03

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值