Reload UIView gradient background

≯℡__Kan透↙ 提交于 2021-01-28 18:15:04

问题


I have set my UIView background colour to a CAGradient layer which works well. I am trying to change this gradient within the application when it is running. If i close and reload the app the new gradient is applied but i want this to work during run time.

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.backGroundView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], color.CGColor, nil];

[self.backGroundView.layer insertSublayer:gradient atIndex:0];

[self.backGroundView setNeedsDisplay];
self.backGroundView.contentMode = UIViewContentModeRedraw;

I have tried both setNeedsDisplay and UIViewContentModeRedraw but neither are updating the UIview background while the app is running?


回答1:


It looks like your gradient.colors array is not initialised properly. It's a bit of a mess on the right side :).

Sometimes a bit of verbosity is warranted, because it makes code more readable, i.e. you split the problem into multiple lines thus your brain is more in control because you better see what is going on. Therefore let's initialise the colors on separate line a see if it works.

    CAGradientLayer *gradient = [CAGradientLayer layer];

    CGColorRef color1 = [UIColor redColor].CGColor;
    CGColorRef color2 = [UIColor greenColor].CGColor;
    gradient.colors = @[  (__bridge id)color1  ,  (__bridge id)color2  ];

    [self.view.layer insertSublayer:gradient atIndex:0];

There's a bit of a trickery. The CoreAnimation framework expects to find CGColor objects inside the array. But the property is of NSArray type and NSArrays really is an array of "id"s, which are "dumb" pointers to any object. So we create our CGColor instances (on separate lines for sanity), and then we (using modern objective C literals for gods sake :) create the array and since you are casting CoreFoundation objects (CGColors) to Foundation object (id) it needs to be bridged.

Now you can reuse the code also in runtime, for example inside a button pressed action. Since you already have a gradient layer in layer hierarchy there already, you need to get a reference to it. (first line does it)

- (IBAction)changeColorsOnbuttonPressed:(id)sender
{
    CAGradientLayer *gradient = [self.view.layer.sublayers firstObject];

    CGColorRef color1 = [UIColor blueColor].CGColor;
    CGColorRef color2 = [UIColor yellowColor].CGColor;
    gradient.colors = @[(__bridge id)color1, (__bridge id)color2];
} 

You should not need to set the view to be dirty with setNeedsLayout and layoutIfNeeded.



来源:https://stackoverflow.com/questions/28647183/reload-uiview-gradient-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!