3

意图:

我想在视图中绘制一个圆圈,我可以从 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 的动画?
4

0 回答 0