简体   繁体   中英

CALayer not rendering background color on devices, works in simulator

I've created a custom button out of layers. I create a bunch of layers in init . Everything works as expected until I go to modify* them. It is only on the actual devices that the problem occurs, on the simulator the code works as expected.

I've tried forcing the layers to render by setting needsDisplay and needsLayout to YES .

-(void) setBackgroundColor:(UIColor *)backgroundColor
{   
    //return; // if I return here, the button gets initialized with it's default royal blue color.  This works correctly on the simulator and device

    [primaryBackground setColors: [NSArray arrayWithObject:(id)backgroundColor.CGColor]];

    //return; //if I return here, primaryBackground will display a clear background on the device, but will display CGColor on the simulator.

    CALayer* ll = [CALayer layer];
    ll.frame=self.frame;
    ll.cornerRadius=primaryBackground.cornerRadius;
    [ll setBackgroundColor:backgroundColor.CGColor];
    [primaryBackground addSublayer:ll];

     //if I return here, primaryBackground will display the "expected" results on both platforms.  IE: it dispalys the new layer, but not it's background color.
}

SIMULATOR

模拟器截图

DEVICE

设备截图

TESTS

I've tested on iOS 5.1 and 4.2 with the same results. Appears to work the same on simulators version 4.1, 4.2 and 5.1

I see at least 2 problems with your code:

  1. You are adding a new layer every time the color is changed, without removing the old one. First, remove the previously created sublayer (or simply change its color without creating and adding a new one). Remember that the default opaque property of CALayer is set to NO , which means it is being blended with all the other sublayers.

    Why adding another sublayer anyway? In your code, you cover primaryBackground completely. Can't setBackgroundColor: function just look like this:

     - (void)setBackgroundColor:(UIColor *)backgroundColor { [primaryBackground setBackgroundColor:backgroundColor.CGColor]; } 

    ?

  2. But if you really must have an additional layer, you should set ll 's frame to the bounds of the superlayer (not frame ). It should be ll.frame = self.bounds . You should also override the - (void)layoutSubivews method and set the frame of the background layer to the bounds of the root layer again.

Remember that, on iPhone Simulator , things are rendered by different subsystem and a lot faster than on real device. And some frame calculations may overlap, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM