0

CALayer の世界へ:

デバイスの向きに関係なく、ビューの中央に留まる必要があるレイヤーを作成しています。スーパーレイヤーからレイヤーを削除したにもかかわらず、古い位置からの回転後にレイヤーがアニメーション化されるのはなぜですか? frame および borderWidth プロパティがアニメーション化可能であることは理解していますが、superLayer から削除した後でもアニメーション化できますか?

また、レイヤーオブジェクトが解放されていないため、スーパーレイヤーから削除してもレイヤープロパティがリセットされない場合(理解できます)、新しく表示されたレイヤーの動作を模倣して、境界線が移動しているように表示されないようにするにはどうすればよいですか回転後の古い位置。

このサンプル プロジェクトを作成しました。必要に応じてカット アンド ペーストしてください。クォーツ コア ライブラリをリンクするだけです。

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()
@property (nonatomic,strong) CALayer *layerThatKeepAnimating;
@end

@implementation ViewController

-(CALayer*) layerThatKeepAnimating
{
  if(!_layerThatKeepAnimating)
  {
    _layerThatKeepAnimating=[CALayer layer];
    _layerThatKeepAnimating.borderWidth=2;
  }
return _layerThatKeepAnimating;
}


-(void) viewDidAppear:(BOOL)animate
{    
self.layerThatKeepAnimating.frame=CGRectMake(self.view.bounds.size.width/2-50,self.view.bounds.size.height/2-50, 100, 100);
  [self.view.layer addSublayer:self.layerThatKeepAnimating];
}


-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
  [self.layerThatKeepAnimating removeFromSuperlayer];
}


-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  self.layerThatKeepAnimating.frame=CGRectMake(self.view.bounds.size.width/2-50,self.view.bounds.size.height/2-50, 100, 100);
  [self.view.layer addSublayer:self.layerThatKeepAnimating];
}

@end
4

3 に答える 3

0

問題はあなたが思っていることではありません。スーパービューからそのレイヤーを削除しても、そのレイヤーへの強い参照を保持しているため、実際には無効化されません。新しいレイヤーを作成するために、コードがゲッターにifステートメントを入力しません。これは、最初のコードがnilになることはないためです。

if(!_layerThatKeepAnimating)
  {
    _layerThatKeepAnimating=[CALayer layer];
    _layerThatKeepAnimating.borderWidth=2;
  }

したがって、vcのレイヤーへの参照をweakに変更します。

@property (nonatomic, weak) CALayer * layerThatKeepAnimating;

または、次の方法で明示的に削除します。

-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
  [self.layerThatKeepAnimating removeFromSuperlayer];
  self.layerThatKeepAnimating = nil;
}

ビューにレイヤー(またはサブビュー)を追加すると、すでに1つの強力な参照が得られるため、最初のオプションを使用することをお勧めします。そのため、常に次のようにすることをお勧めします。

@property (weak, nonatomic) IBOutlet UIView *view;

しかしそうではありません(強力で非原子的)。

于 2013-02-24T22:05:06.863 に答える
0
[self.sublayerToRemove removeFromSuperlayer];
self.sublayerToRemove = nil;
于 2016-10-13T14:01:42.917 に答える
0

奇妙に聞こえるかもしれませんが、答えはコードを移動することです

willRotateToInterfaceOrientation to viewWillLayoutSubviews

-(void) viewWillLayoutSubviews
{
    self.layerThatKeepAnimating.frame=CGRectMake(self.view.bounds.size.width/2-50,self.view.bounds.size.height/2-50, 100, 100);
    [self.view.layer addSublayer:self.layerThatKeepAnimating];
}

ここでのレイヤーの「再描画」は、レイヤーのプロパティがアニメーション化可能であっても、アニメーションなしで発生するようです。

于 2013-02-24T16:52:00.740 に答える