CALayer自动调整大小在iPhone/iPad上的应用:如何实现?

21

我试图创建一个UIView子类("GradientView"),它将用各种颜色的渐变填充自己。我通过在UIView的层中添加CAGradientLayer作为子层来实现它。

看起来很好,但当屏幕旋转时,它没有重新调整渐变层的大小。找不到可以切换层上的BOOL属性,因此我在GradientView中重写了layoutSubviews。

-(void)layoutSubviews {
    self.gradientLayer.frame = self.bounds;
}

这个方法可行,但在设备旋转动画期间,GradientView 后面的东西仍然可见。最简单的方法是什么,可以将 CAGradientLayer “自动调整大小”以匹配其父层的边界,以使动画平滑(类似于 UIView 的自动调整大小)?

5个回答

29

您可以在自定义的 UIView 上定义 +layerClass 方法,可能会奏效...

@implementation MyGradientView
+(Class) layerClass {
    return [CAGradientLayer class];
}
@end

您可以在控制器的viewDidLoad()方法(或任何其他地方)中初始化层,例如...

-(void)viewDidLoad {
    [super viewDidLoad];
    [(CAGradientLayer*)[mMyGradientViewInstance layer] setColors:nil];
}

2
+1 很好地工作。图层大小由父UIView管理,并自动调整大小。 - Adolfo
7
这个答案不是很清楚。我已经尝试了很多小时但没有成功。 - DavidNg
非常好用!任何想在分组的UITableViewCells上使用它的人,不要忘记需要子类化一个普通的UIView并将其设置为单元格的backgroundView(而不是子类化单元格本身)。 - SpacyRicochet
2
我认为这里缺少的信息是通过子类化此方法,您使创建的图层成为视图的主“图层”。由于它是视图的主图层,因此框架会根据需要自动调整其大小。 - Shaun Budhram

4
我会:
  1. 增加在willRotateToInterfaceOrientation代码中每个维度的视图大小最大化。(例如,对于320x480 iPhone - 将dims设置为480x480)。

  2. 根据新旋转的视图在didRotateFromInterfaceOrientation函数中设置边界。

这样做可以使视图足够大,以便无论在动画期间如何定位,它都将覆盖整个屏幕。它不会是“平滑”的 - 因为梯度必须被旋转,但至少您不会在旋转过程中看到中间图层后面的内容。


1
好的 - 有更好的想法吗?我在制作映射程序时使用这种技术,在其中我必须从320x480旋转到480x320,并希望它看起来无缝。 - Brad
请查看下降投票的标准:http://stackoverflow.com/privileges/vote-down - Brad
教训是,Brad你能编辑一下你的回答吗?(即使只是将一个单词大写)我会把DV撤下来。(除非编辑,否则投票已锁定) - Luke Mcneice
这有点像是一个hack,但是由于你可以将视图剪切到其边界,所以它可以工作。 - Magoo

2
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    CGRect b;

    if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation))b = CGRectMake(0, 0, 480, 320);
    else b = CGRectMake(0, 0, 320, 480);    

    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];
    [self.view.layer setBounds:b];
    [CATransaction commit];

}

你认为我们为什么需要明确更改层的边界?当关联视图的框架更改时,层应自动调整大小,不是吗? - Raj Pawan Gumdal

1
请注意,仅当您将视图背景颜色设置为透明时,将CAGradientLayer作为层类返回才有效。如果您需要其他颜色而不是透明,请设置层背景颜色。

0

在我的情况下,这个工作:

[[[view.layer sublayers] objectAtIndex:gradientIndex] setFrame:view.bounds];

我将您的代码添加到(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration中。当我旋转时,旧图层仍然存在。新的横向模式图层仍然出现。请帮我。 - DavidNg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接