即使从超级层移除后,CALayer帧值也会导致动画

时间:2013-02-24 16:31:26

标签: ios uiview uiviewcontroller calayer quartz-core

进入CALayer世界:

我正在创建一个无论设备方向如何都需要保持在视图中间的图层。有人能告诉我为什么我的图层在从旧位置旋转后动画,即使我从超级图层中删除了它?我知道frame和borderWidth属性是可动画的,但即使从superLayer中删除后它们也可以动画化吗?

如果从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

3 个答案:

答案 0 :(得分:0)

这听起来很奇怪,答案是在

中移动代码

willRotateToInterfaceOrientation 至 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];
}

它看起来像任何一层&#34;重绘&#34;这里没有动画,即使图层属性是可动画的。

答案 1 :(得分:0)

问题不在于你的想法;当您从超级视图中删除该图层时,它实际上并未被限制,因为您保留了对它的强引用。您的代码不会在getter中输入if语句来创建新图层,因为它在第一次之后永远不会为零:

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

因此要么将对vc中图层的引用更改为弱:

@property (nonatomic, weak) CALayer * layerThatKeepAnimating;

或者通过以下方式明确删除它:

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

我建议您使用第一个选项,因为当您向视图添加图层(或子视图)时,您已经获得了一个强引用。这就是为什么总是建议这样做:

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

但不是(强,非原子)。

答案 2 :(得分:0)

[self.sublayerToRemove removeFromSuperlayer];
self.sublayerToRemove = nil;