多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 组透明     UIView有一个叫做`alpha`的属性来确定视图的透明度。CALayer有一个等同的属性叫做`opacity`,这两个属性都是影响子层级的。也就是说,如果你给一个图层设置了`opacity`属性,那它的子图层都会受此影响。     iOS常见的做法是把一个控件的alpha值设置为0.5(50%)以使其看上去呈现为不可用状态。对于独立的视图来说还不错,但是当一个控件有子视图的时候就有点奇怪了,图4.20展示了一个内嵌了UILabel的自定义UIButton;左边是一个不透明的按钮,右边是50%透明度的相同按钮。我们可以注意到,里面的标签的轮廓跟按钮的背景很不搭调。 ![](https://box.kancloud.cn/2015-12-24_567bc1f64ffc2.png) 图4.20 右边的渐隐按钮中,里面的标签清晰可见     这是由透明度的混合叠加造成的,当你显示一个50%透明度的图层时,图层的每个像素都会一半显示自己的颜色,另一半显示图层下面的颜色。这是正常的透明度的表现。但是如果图层包含一个同样显示50%透明的子图层时,你所看到的视图,50%来自子视图,25%来了图层本身的颜色,另外的25%则来自背景色。     在我们的示例中,按钮和表情都是白色背景。虽然他们都是50%的可见度,但是合起来的可见度是75%,所以标签所在的区域看上去就没有周围的部分那么透明。所以看上去子视图就高亮了,使得这个显示效果都糟透了。     理想状况下,当你设置了一个图层的透明度,你希望它包含的整个图层树像一个整体一样的透明效果。你可以通过设置Info.plist文件中的`UIViewGroupOpacity`为YES来达到这个效果,但是这个设置会影响到这个应用,整个app可能会受到不良影响。如果`UIViewGroupOpacity`并未设置,iOS 6和以前的版本会默认为NO(也许以后的版本会有一些改变)。     另一个方法就是,你可以设置CALayer的一个叫做`shouldRasterize`属性(见清单4.7)来实现组透明的效果,如果它被设置为YES,在应用透明度之前,图层及其子图层都会被整合成一个整体的图片,这样就没有透明度混合的问题了(如图4.21)。     为了启用`shouldRasterize`属性,我们设置了图层的`rasterizationScale`属性。默认情况下,所有图层拉伸都是1.0, 所以如果你使用了`shouldRasterize`属性,你就要确保你设置了`rasterizationScale`属性去匹配屏幕,以防止出现Retina屏幕像素化的问题。     当`shouldRasterize`和`UIViewGroupOpacity`一起的时候,性能问题就出现了(我们在第12章『速度』和第15章『图层性能』将做出介绍),但是性能碰撞都本地化了(译者注:这句话需要再翻译)。 清单4.7 使用`shouldRasterize`属性解决组透明问题 ~~~ @interface ViewController () @property (nonatomic, weak) IBOutlet UIView *containerView; @end @implementation ViewController - (UIButton *)customButton { //create button CGRect frame = CGRectMake(0, 0, 150, 50); UIButton *button = [[UIButton alloc] initWithFrame:frame]; button.backgroundColor = [UIColor whiteColor]; button.layer.cornerRadius = 10; //add label frame = CGRectMake(20, 10, 110, 30); UILabel *label = [[UILabel alloc] initWithFrame:frame]; label.text = @"Hello World"; label.textAlignment = NSTextAlignmentCenter; [button addSubview:label]; return button; } - (void)viewDidLoad { [super viewDidLoad]; //create opaque button UIButton *button1 = [self customButton]; button1.center = CGPointMake(50, 150); [self.containerView addSubview:button1]; //create translucent button UIButton *button2 = [self customButton];  button2.center = CGPointMake(250, 150); button2.alpha = 0.5; [self.containerView addSubview:button2]; //enable rasterization for the translucent button button2.layer.shouldRasterize = YES; button2.layer.rasterizationScale = [UIScreen mainScreen].scale; } @end ~~~ ![](https://box.kancloud.cn/2015-12-24_567bc1f66e58d.png) 图4.21 修正后的图