`CAGradientLayer`根据局部坐标空间定义起点和终点

时间:2015-05-06 17:16:57

标签: ios objective-c cocoa core-animation cagradientlayer

CAGradientLayer有两个属性startPointendPoint。这些属性是根据单位坐标空间定义的。结果是,如果我有两个具有相同起点和终点的渐变层,每个渐变层具有不同的边界,则两个渐变将是不同的。

如何定义startPoint图层的endPointCAGradientLayer不是按单位坐标空间而是按标准点坐标定义,以便渐变的角度/大小为不受图层边界的影响?

理想的结果是渐变图层可以调整为任何大小或形状,并且渐变保持不变,尽管裁剪的方式不同。

资格: 我知道这似乎是坐标空间之间的一个绝对微不足道的转换,但显然也是,是的,我实际上是愚蠢的,或者可能有一些关于CAGradientLayer如何工作的破坏或极端反直觉的东西。我没有列举一个我期望应该是正确方法的例子,因为(假设我只是愚蠢)它只会产生误导。

修改

以下是CALayer的实现,它添加了一个子CAGradientLayer并配置它的起点和终点。它不会产生预期的结果。

@interface MyLayer ()
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
@end

@implementation MyLayer

- (instancetype)init {
    if (self = [super init]) {
        self.gradientLayer = [CAGradientLayer new];
        [self addSublayer:self.gradientLayer];
        self.gradientLayer.colors = @[ (id)[UIColor redColor].CGColor,  (id)[UIColor orangeColor].CGColor, (id)[UIColor greenColor].CGColor, (id)[UIColor blueColor].CGColor];;
        self.gradientLayer.locations = @[ @0, @.333, @.666, @1 ];
    }
    return self;
}

- (void)layoutSublayers {
    [super layoutSublayers];
    self.gradientLayer.frame = self.bounds;
    self.gradientLayer.startPoint = CGPointMake(0, 0);
    self.gradientLayer.endPoint = CGPointMake(100 / self.bounds.size.width, 40 / self.bounds.size.height);
}

@end

我有一个.xib文件,其中包含许多不同大小的MyLayer个文件。层的梯度都是不同的。

2 个答案:

答案 0 :(得分:1)

否则无法定义startPoint和endPoint。您有两种选择:

  • 根据视图高度计算出来(100像素视图高度为50像素= 0.5,对于100像素视图高度= 0.25)

  • 以所需的最大固定大小创建渐变(例如:高度为568),并将其添加为另一个视图的子视图,该视图将根据您的需要调整大小,并启用clipsToBounds。这样,你可以达到你想要的效果(渐变始终从顶部开始并剪切底部,保持渐变居中并夹住顶部和底部等)

答案 1 :(得分:0)

  

如何定义CAGradientLayer图层的startPoint和endPoint不是在单位坐标空间方面而是在标准点坐标方面,以便渐变的角度/大小不受图层边界的影响?

它不能。但是你可以很容易地想到一个不同的策略。例如:

  • 以不同的方式绘制渐变(使用Quartz而不是依靠CAGradientLayer为您绘制)。

  • 使用蒙版使图层显示为某个尺寸和形状,您可以通过更改蒙版来更改该尺寸和形状,但实际上图层本身就是一个不断变化的图层始终具有相同的渐变。

  • 检测渐变图层是否更改了边界,并更改渐变startPointendPoint以匹配。这是一个视图的工作示例,其图层是渐变图层并执行此操作 - 但您必须记住每次边界更改时重绘图层!

    override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
        let grad = layer as! CAGradientLayer
        grad.colors = [UIColor.whiteColor().CGColor, UIColor.redColor().CGColor]
        let maxx:CGFloat = 500.0 // or whatever
        let maxy:CGFloat = 500.0 // or whatever
        grad.startPoint = CGPointMake(0,0) // or whatever!
        grad.endPoint = CGPointMake(maxx/self.bounds.width, maxy/self.bounds.height)
    }
    

enter image description here

enter image description here