意图:
我想在视图中绘制一个圆圈,我可以从 ViewController 移动、调整大小和重新着色。
设置:
我将 UIView 子类化以创建一个仅保持圆圈的视图:
@implementation CircleView
+ (Class)layerClass //override
{
return [CAShapeLayer class];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.opaque = NO;
CAShapeLayer *layer = (CAShapeLayer *)self.layer;
layer.fillColor = nil;
layer.strokeColor = [UIColor colorWithWhite:1 alpha:1].CGColor;
layer.lineWidth = 2;
}
return self;
}
-(void) layoutSubviews
{
CAShapeLayer *layer = (CAShapeLayer *)self.layer;
layer.path = [UIBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;
}
@end
然后我在父视图initWithFrame中像这样初始化它:
{
CGFloat diam = MIN(frame.size.width, frame.size.height);
self.circleView = [[VCCCircleView alloc] initWithFrame:ASRectCenteredOnPoint(ASRectGetCenter(frame), (CGSize){diam,diam})];
self.circleView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
[self addSubview:self.circleView];
}
最后,父视图还提供了一个动画视图的方法:
-(void)setCircleFrame:(CGRect)frame
{
CAShapeLayer *layer = (CAShapeLayer *)self.circleView.layer;
[UIView animateWithDuration:1 delay:10 options:UIViewAnimationOptionLayoutSubviews animations:^(void)
{
circleView.frame = frame;
//for debug: circleView.frame = CGRectInset(circleView.frame, -30, -30);
} completion:nil];
}
这个想法是你可以只设置框架,圆圈会移动和调整大小。简单吧?
问题:
圆圈*不*动画它的大小变化,但它确实动画它的位置变化。- 结果是它跳到新的大小,然后动画原点的运动。这在我为动画引入的大延迟中尤为明显。
我注意到,如果我只是更改圆圈的位置,则不会调用 circleView 的 layoutSubviews,但如果我更改了边界,则会调用它。
我没有使用任何转换。
我试过的:
- 从圆形视图的初始化中删除 autoresizemask 的东西
- 动画选项的各种组合(包括
BeginFromCurrentState
:) - 设置新帧后在动画块中调用[self layoutSubviews]
- 编辑边界而不是框架
- 以上的组合
我没有尝试过的:
- 直接使用 CABasicAnimation。这是必要的吗?'Frame' 应该是 UIView 的动画?