目的:
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 を直接使用する。これは必要ですか?「フレーム」はUIViewのアニメーション化可能であるはずですか?