web-dev-qa-db-ja.com

UIViewのサイズを変更しながらアニメーション化する方法

Webでいくつかの資料を見ましたが、それでも、希望する場所に到達できません。ビューを下向きにアニメーション化して、高さを大きくする必要があります。

これが私のコードです。ここで何が起こっているかというと、ビューのサイズを変更する代わりに、位置を少し変更しているだけです。 「bounds.size」の代わりにプロパティを「transform.scale.y」に変更すると、少しだけ良くなります。今回は、ビューを下だけでなく上下に拡大します。

私がそうではないもう1つのこと:これらのキーはCALayerプロパティだけですか?これらのキーのリストはどこにありますか?

ここで助けていただければ幸いです。ありがとう!

int x = self.btnHead.frame.Origin.x;
int y = self.btnHead.frame.Origin.y;
int height = self.btnHead.frame.size.height;
int width = self.btnHead.frame.size.width;


CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
[resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(width,height+50)]];
resizeAnimation.fillMode = kCAFillModeForwards;
resizeAnimation.removedOnCompletion = NO;

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = [NSArray arrayWithObjects:resizeAnimation,nil];
animationGroup.removedOnCompletion = NO;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.removedOnCompletion=NO;
animationGroup.duration = 0.1;

[self.btnHead.layer addAnimation:animationGroup forKey:@"animations"];

編集:要求に応じて最初のコードを投稿します-これにより、ビューのサイズが変更されるだけですが、入力した時間に関係なく、アニメーション化されません。

    int x = self.btnHead.frame.Origin.x;
    int y = self.btnHead.frame.Origin.y;
    int height = self.btnHead.frame.size.height;
    int width = self.btnHead.frame.size.width;


    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:10];
    CGRect rect = CGRectMake(x,y,width ,height+BUTTON_HEIGH*2);

    self.btnHead.frame = rect;

    [UIView commitAnimations];
17
Idan
btnHead.clipsToBounds=YES

問題を解決しました。理由は正確にはわかりません。

10
Idan

frameプロパティをアニメーション化すると問題が発生する可能性がありますが、transformがIDである限り(つまり、変更していない限り)、正しく機能するはずです。次のコードをテストしたところ、期待どおりに動作しました。

[UIView animateWithDuration:.1f animations:^{
  CGRect theFrame = myView.frame;
  theFrame.size.height += 50.f;
  myView.frame = theFrame;
}];

繰り返しますが、transformプロパティをいつでも変更した場合、これは期待どおりに機能しません。このアニメーションのより完全なバージョンでは、Core Animationで試したようにboundsプロパティをアニメーション化する必要があります。ただし、コアアニメーションにドロップする必要はありません。

ここで理解しておくべき重要なことは、boundsプロパティとcenterプロパティの関係です。すべてのアフィン変換(変換、スケーリング、または回転)には、変換を実行する基準点が必要です。 UIViewの場合は、centerポイントです。 CALayerを使用すると、anchorPointプロパティを介して参照ポイントを移動できますが、この場合、そのことを心配する必要はありません。

ビューが両方向に拡大縮小する理由は、拡大縮小操作がcenterを中心に行われるためです。そのための最も簡単な方法は、centeryを高さデルタの半分だけ移動することです。このような:

myView.contentMode = UIViewContentModeRedraw;
[UIView animateWithDuration:.4f animations:^{
  CGRect theBounds = myView.bounds;
  CGPoint theCenter = myView.center;
  theBounds.size.height += 50.f;
  theCenter.y += 25.f;
  myView.bounds = theBounds;
  myView.center = theCenter;
}];

最後の考慮事項は、boundsが変更されたときにビューを強制的に再描画することです。パフォーマンス上の理由から、boundsを変更してもビューは再描画されません。ただし、frameプロパティを変更すると再描画されます(frameプロパティのもう1つの奇妙な点)。 boundsの変更時に強制的に再描画するには、前のスニペットの最初の行で行ったように、contentModeを設定する必要があります。アニメーションの終了後に設定を戻したいと思うかもしれませんが、それはあなた次第です。これは、Core Animationバージョンが場所ではなくサイズを変更する理由でもあります。アニメーションを実行する前に、コードのどこかにこの行が必要です。

self.btnHead.layer.needsDisplayOnBoundsChange = YES;

これがすべて理にかなっているといいのですが。 framebounds、およびcenterプロパティは、最初は少し混乱することがあります。

53
Nathan Eror

UIViewアニメーションブロック内のフレームを変更することはできませんか?この場合、CABasicAnimationは必要ないようです。

 [UIView beginAnimations:@ "resize_animation" context:NULL]; 
 //期間を設定します。長い期間をデバッグする方が良いです。
 // 0.1は、何が問題なのかを理解するのに本当に短いです。 
 
 btnHead.frame = newFrame; 
 
 [UIView commitAnimations]; 
8
taskinoor

clipsToBoundsがソリューションです。

説明:clipToBoundsは、subviewsをトリミングするかどうかを指定するプロパティです。したがって、subviewがそのスーパービューよりも大きい場合、"superview.clipToBounds=YES"を設定するとトリミングされます。この投稿の場合、スーパービューはサイズ変更されましたが、フレームの外側にある場合でもサブビューが描画されたため、ユーザーには目に見える違いはありませんでした。

アニメーションとの目に見えるリンクがないため、少し注意が必要ですが、このため、このプロパティが違いを生みます。

2
Toom