Iphone 仅在自定义UIView中执行动画
我面临着和你一样的问题 我有一个自定义的Iphone 仅在自定义UIView中执行动画,iphone,ios,Iphone,Ios,我面临着和你一样的问题 我有一个自定义的ui视图 MyUIView 当前,每当我单击具有不同于旧值的新值的按钮时,我都可以看到圆角矩形从旧位置移动到新位置,但没有动画。 我想有动画,只有在显式按钮点击。对于我所看到的大多数示例,动画代码是在控制器中通过 动画通过层和CGPathCreateMutable完成 层和CGPathCreateMutable的创建在视图控制器中执行 我想知道,我如何能够通过单击的MyUIView的setvaluevia按钮执行上述任务?由于drawRect中没有正确
ui视图
MyUIView
当前,每当我单击具有不同于旧值的新值的按钮时,我都可以看到圆角矩形从旧位置移动到新位置,但没有动画。
我想有动画,只有在显式按钮点击。对于我所看到的大多数示例,动画代码是在控制器中通过
- 动画通过层和CGPathCreateMutable完成
- 层和CGPathCreateMutable的创建在视图控制器中执行
我想知道,我如何能够通过单击的
MyUIView
的setvaluevia按钮执行上述任务?由于drawRect中没有正确的rect
信息,我如何为从CGPathCreateMutable
创建的路径配置信息?我认为您不使用CoreAnimation
而是使用CoreGraphics
仅绘制当前状态/值。每当涉及到动画而不是静态图像时,我都会切换到CoreAnimation
层。在您的例子中,我将创建一个UIView
子类,并为三角形(或任何形状)添加一个CAShapeLayer
它看起来是这样的:
@interface MyView ()
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
@property (nonatomic, assign) double currentValue;
@end
@implementation MyView
-(instancetype)init {
if (self = [super init]) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self setup];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
CAShapeLayer *shape = [CAShapeLayer layer];
shape.contentsScale = [[UIScreen mainScreen] scale];
self.shapeLayer = shape;
[self.layer addSublayer:shape];
}
- (void)layoutSubviews {
[super layoutSubviews];
self.shapeLayer.frame = self.bounds;
self.shapeLayer.path = [self bezierPathForValue:self.currentValue].CGPath;
}
- (UIBezierPath *)bezierPathForValue:(double)value {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:...]; // points are depending on currentValue
return path;
}
- (void)setValueViaButtonClicked:(double) value {
double oldValue = self.currentValue;
self.currentValue = value;
// update model value
self.shapeLayer.path = [self bezierPathForValue:value].CGPath;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (id)[self bezierPathForValue:oldValue].CGPath;
pathAnimation.toValue = (id)[self bezierPathForValue:value].CGPath;
pathAnimation.duration = 0.3f;
[self.shapeLayer addAnimation:pathAnimation forKey:nil];
}
@end
@interface MyView ()
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
@property (nonatomic, assign) double currentValue;
@end
@implementation MyView
-(instancetype)init {
if (self = [super init]) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self setup];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
CAShapeLayer *shape = [CAShapeLayer layer];
shape.contentsScale = [[UIScreen mainScreen] scale];
self.shapeLayer = shape;
[self.layer addSublayer:shape];
}
- (void)layoutSubviews {
[super layoutSubviews];
self.shapeLayer.frame = self.bounds;
self.shapeLayer.path = [self bezierPathForValue:self.currentValue].CGPath;
}
- (UIBezierPath *)bezierPathForValue:(double)value {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:...]; // points are depending on currentValue
return path;
}
- (void)setValueViaButtonClicked:(double) value {
double oldValue = self.currentValue;
self.currentValue = value;
// update model value
self.shapeLayer.path = [self bezierPathForValue:value].CGPath;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (id)[self bezierPathForValue:oldValue].CGPath;
pathAnimation.toValue = (id)[self bezierPathForValue:value].CGPath;
pathAnimation.duration = 0.3f;
[self.shapeLayer addAnimation:pathAnimation forKey:nil];
}
@end