2011-07-07 5 views
3

私にはわからない奇妙なバグがあります。私は少し輝いているアニメーションを作成していますが、これは完璧に動作しますが、何らかの理由でUINavigationControllerまたはUITabViewを介して別のビューに移動すると停止します(不思議なモーダルビューは影響を与えません)。どのようなアイデア、なぜ、どのように私はアニメーションが停止しないことを確認することができますか?UINavigationControllerまたはUITabViewを使用するとアニメーションが停止する

UIView *whiteView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; 
[whiteView setBackgroundColor:[UIColor whiteColor]]; 
[whiteView setUserInteractionEnabled:NO]; 
[self.view addSubview:whiteView]; 

CALayer *maskLayer = [CALayer layer]; 

maskLayer.backgroundColor = [[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.0f] CGColor]; 
maskLayer.contents = (id)[[UIImage imageNamed:@"ShineMask.png"] CGImage]; 

// Center the mask image on twice the width of the text layer, so it starts to the left 
// of the text layer and moves to its right when we translate it by width. 
maskLayer.contentsGravity = kCAGravityCenter; 
maskLayer.frame = CGRectMake(-whiteView.frame.size.width, 
          0.0f, 
          whiteView.frame.size.width * 2, 
          whiteView.frame.size.height); 

// Animate the mask layer's horizontal position 
CABasicAnimation *maskAnim = [CABasicAnimation animationWithKeyPath:@"position.x"]; 
maskAnim.byValue = [NSNumber numberWithFloat:self.view.frame.size.width * 9]; 
maskAnim.repeatCount = HUGE_VALF; 
maskAnim.duration = 3.0f; 
[maskLayer addAnimation:maskAnim forKey:@"shineAnim"]; 

whiteView.layer.mask = maskLayer; 
+0

何メソッドは、このコードを実行? – cduhn

+0

このコードはカスタムUIViewControllerオブジェクトの一部です。オブジェクトは別のビューで初期化され、そのビューからメソッドが呼び出されます。 – Rob

答えて

0

あなたmaskAnimはself.viewによって保持されているwhiteView、によって保持されるwhiteViewの層によって保持されているマスク層によって保持されています。したがって、この全体のオブジェクトグラフは、ビューコントローラのビューがdeallocされるまで生き続けます。

ビューコントローラから離れて移動すると、UIKitによってビューがアンロードされ、メモリが解放されます。ビューがdeallocされたとき、あなたのmaskAnimもそうです。ビューコントローラに戻ると、UIKitは、使用した手法に応じて、.xibからリロードしたり、loadViewを呼び出すことによって、ビュー階層を再構築します。

したがって、UIKitがビュー階層を再構築した後に、あなたのmaskAnimの設定に使用したコードが再度呼び出されるようにする必要があります。考慮する4つのメソッドがあります:loadView、viewDidLoad、viewWillAppear :,およびviewDidAppear:

loadViewは、その方法を使用して(.xibからロードするのではなく)ビュー階層を構築する場合には分かりやすいオプションですが、自己に依存しないようにコードを変更する必要があります.viewプロパティは、loadViewを再帰的にトリガします。 viewDidLoadも良い選択です。これらのオプションのいずれかを使用すると、正しいサイズで構築されていないと、viewDidLoadの後にUIKitがビューのサイズを変更する可能性があるため、注意が必要です。これは、コードがself.view.frame.size.widthに依存するため、バグを引き起こす可能性があります。

viewWillAppear:またはviewDidAppear:でアニメーションを設定すると、ビューのフレームが適切な次元になることが確かめられますが、これらのメソッドは、後で複数回呼び出される可能性があるため注意が必要です。ビューがロードされ、whiteViewサブビューを複数回追加する必要はありません。

何だろう、おそらくやるviewWillAppearでwhiteView保持特性、および遅延読み込み、それを作るものです。このように:

- (UIView *)setupWhiteViewAnimation { 
    // Execute your code above to setup the whiteView without adding it 
    return whiteView; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    if (!self.whiteView) { 
     self.whiteView = [self setupWhiteViewAnimation]; 
     [self.view addSubview:self.whiteView]; 
    } 
} 

- (void)viewDidUnload { 
    self.whiteView = nil; // Releases your whiteView when the view is unloaded 
    [super viewDidUnload]; 
} 

- (void)dealloc { 
    self.whiteView = nil; // Releases your whiteView when the controller is dealloc'd 
    [super dealloc]; 
} 
関連する問題