gpt4 book ai didi

ios - CALayer 没有像 UIView 动画一样的动画

转载 作者:可可西里 更新时间:2023-11-01 03:26:38 25 4
gpt4 key购买 nike

我有一个包含 16 个子层以形成 Logo 的类。当我为 UIView 设置动画时,CALayers 没有设置动画,而是进入最终状态,如下面的动画 gif 所示:

enter image description here

我的代码是:

@implementation LogoView

#define CGRECTMAKE(a, b, w, h) {.origin={.x=(a),.y=(b)},.size={.width=(w),.height=(h)}}

#pragma mark - Create Subviews
const static CGRect path[] = {
CGRECTMAKE(62.734375,-21.675000,18.900000,18.900000),
CGRECTMAKE(29.784375,-31.725000,27.400000,27.300000),
CGRECTMAKE(2.534375,-81.775000,18.900000,18.900000),
CGRECTMAKE(4.384375,-57.225000,27.400000,27.300000),
CGRECTMAKE(2.784375,62.875000,18.900000,18.900000),
CGRECTMAKE(4.334375,29.925000,27.400000,27.300000),
CGRECTMAKE(62.734375,2.525000,18.900000,18.900000),
CGRECTMAKE(29.784375,4.475000,27.400000,27.300000),
CGRECTMAKE(-21.665625,-81.775000,18.900000,18.900000),
CGRECTMAKE(-31.765625,-57.225000,27.400000,27.300000),
CGRECTMAKE(-81.615625,-21.425000,18.900000,18.900000),
CGRECTMAKE(-57.215625,-31.775000,27.400000,27.300000),
CGRECTMAKE(-81.615625,2.775000,18.900000,18.900000),
CGRECTMAKE(-57.215625,4.425000,27.400000,27.300000),
CGRECTMAKE(-21.415625,62.875000,18.900000,18.900000),
CGRECTMAKE(-31.765625,29.925000,27.400000,27.300000)
};

- (void) createSubviews
{

self.contentMode = UIViewContentModeRedraw;
for (int i = 0; i < 16; i++) {
CGRect rect = CGRectApplyAffineTransform(path[i],
CGAffineTransformMakeScale(self.frame.size.width / 213.0,
self.frame.size.height / 213.0));
UIBezierPath * b = [UIBezierPath bezierPathWithOvalInRect:
CGRectOffset(rect,
self.frame.size.width/2.0,
self.frame.size.height/2)];
CAShapeLayer * layer = [[CAShapeLayer alloc] init];
layer.path = [b CGPath];
layer.fillColor = [self.tintColor CGColor];
[self.layer addSublayer:layer];
}
self.layer.needsDisplayOnBoundsChange = YES;
self.initialLenght = self.frame.size.width;
}

- (void) layoutSublayersOfLayer:(CALayer *)layer
{
for (int i = 0; i < 16; i++) {
CGRect rect = CGRectApplyAffineTransform(path[i],
CGAffineTransformMakeScale(layer.frame.size.width / 213.0,
layer.frame.size.height / 213.0));
UIBezierPath * b = [UIBezierPath
bezierPathWithOvalInRect:CGRectOffset(rect,
layer.frame.size.width/2.0,
layer.frame.size.height/2)];
((CAShapeLayer*)(layer.sublayers[i])).path = b.CGPath;
}
}

- (void)layoutSubviews {
[super layoutSubviews];

// get current animation for bounds
CAAnimation *anim = [self.layer animationForKey:@"bounds"];

[CATransaction begin];
if(anim) {
// animating, apply same duration and timing function.
[CATransaction setAnimationDuration:anim.duration];
[CATransaction setAnimationTimingFunction:anim.timingFunction];

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
[self.layer addAnimation:pathAnimation forKey:@"path"];
}
else {
// not animating, we should disable implicit animations.
[CATransaction disableActions];
}
self.layer.frame = self.frame;
[CATransaction commit];
}

我正在制作动画:

    [UIView animateWithDuration:3.0 animations:^{
[v setFrame:CGRectMake(0.0, 0.0, 300.0, 300.0)];
}];

如何同步图层动画和 View 动画?

最佳答案

与 UIView 动画同步的动画层属性可能很棘手。相反,让我们使用不同的 View 结构来利用对动画 View 的 transform 进行动画处理的内置支持,而不是尝试对层的 path 进行动画处理。

我们将使用两个 View :一个父 View 和一个 subview 。 superview 是一个 LogoView 并且是我们在 Storyboard 中布局的(或者您创建 UI 的任何方式)。 LogoView 将 subview 添加到类 LogoLayerView 中。这个 LogoLayerView 使用 CAShapeLayer 作为它的图层而不是普通的 CALayer

请注意,我们只需要一个 CAShapeLayer,因为一条路径可以包含多个断开连接的区域。

我们将 LogoLayerView 的框架/边界设置为 CGRectMake(0, 0, 213, 213) 一次,并且永远不会更改它。相反,当外部 LogoView 改变大小时,我们设置 LogoLayerViewtransform 以便它仍然填充外部 LogoView.

结果如下:

logo scaling

代码如下:

Logo View .h

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface LogoView : UIView

@end

标志 View .m

#import "LogoView.h"

#define CGRECTMAKE(a, b, w, h) {.origin={.x=(a),.y=(b)},.size={.width=(w),.height=(h)}}

const static CGRect ovalRects[] = {
CGRECTMAKE(62.734375,-21.675000,18.900000,18.900000),
CGRECTMAKE(29.784375,-31.725000,27.400000,27.300000),
CGRECTMAKE(2.534375,-81.775000,18.900000,18.900000),
CGRECTMAKE(4.384375,-57.225000,27.400000,27.300000),
CGRECTMAKE(2.784375,62.875000,18.900000,18.900000),
CGRECTMAKE(4.334375,29.925000,27.400000,27.300000),
CGRECTMAKE(62.734375,2.525000,18.900000,18.900000),
CGRECTMAKE(29.784375,4.475000,27.400000,27.300000),
CGRECTMAKE(-21.665625,-81.775000,18.900000,18.900000),
CGRECTMAKE(-31.765625,-57.225000,27.400000,27.300000),
CGRECTMAKE(-81.615625,-21.425000,18.900000,18.900000),
CGRECTMAKE(-57.215625,-31.775000,27.400000,27.300000),
CGRECTMAKE(-81.615625,2.775000,18.900000,18.900000),
CGRECTMAKE(-57.215625,4.425000,27.400000,27.300000),
CGRECTMAKE(-21.415625,62.875000,18.900000,18.900000),
CGRECTMAKE(-31.765625,29.925000,27.400000,27.300000)
};

#define LogoDimension 213.0

@interface LogoLayerView : UIView
@property (nonatomic, strong, readonly) CAShapeLayer *layer;
@end

@implementation LogoLayerView

@dynamic layer;

+ (Class)layerClass {
return [CAShapeLayer class];
}

- (void)layoutSubviews {
[super layoutSubviews];
if (self.layer.path == nil) {
[self initShapeLayer];
}
}

- (void)initShapeLayer {
self.layer.backgroundColor = [UIColor yellowColor].CGColor;
self.layer.strokeColor = nil;
self.layer.fillColor = [UIColor greenColor].CGColor;

UIBezierPath *path = [UIBezierPath bezierPath];
for (size_t i = 0; i < sizeof ovalRects / sizeof *ovalRects; ++i) {
[path appendPath:[UIBezierPath bezierPathWithOvalInRect:ovalRects[i]]];
}
[path applyTransform:CGAffineTransformMakeTranslation(LogoDimension / 2, LogoDimension / 2)];
self.layer.path = path.CGPath;
}

@end

@implementation LogoView {
LogoLayerView *layerView;
}

- (void)layoutSubviews {
[super layoutSubviews];

if (layerView == nil) {
layerView = [[LogoLayerView alloc] init];
layerView.layer.anchorPoint = CGPointZero;
layerView.frame = CGRectMake(0, 0, LogoDimension, LogoDimension);
[self addSubview:layerView];
}
[self layoutShapeLayer];
}

- (void)layoutShapeLayer {
CGSize mySize = self.bounds.size;
layerView.transform = CGAffineTransformMakeScale(mySize.width / LogoDimension, mySize.height / LogoDimension);
}

@end

关于ios - CALayer 没有像 UIView 动画一样的动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33288208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com