CALayer的边框出现在子视图之上(我认为这与Z顺序有关)

18

我已经搜索过但找不到这种行为的原因。

我有一个设置图像的UIButton。下面是按钮应该出现的样子。请注意,这只是所需按钮设计的Photoshop:

enter image description here

本质上,它是一个带有白色边框和一些周围阴影的正方形自定义UIButton。在右上角,将作为子视图以编程方式添加“X”标记。

以下是实际应用程序中按钮的屏幕截图。此时,我仅添加了一个阴影和一个作为子视图的X标记:

enter image description here

然而,当我尝试添加白色边框时,它看起来像这样:

enter image description here

似乎白色边框出现在X标记子层之上。我不知道为什么。

以下是我正在使用的代码:

// selectedPhotoButton is the UIButton with UIImage set earlier
// At this point, I am adding in the shadow
[selectedPhotoButton layer] setShadowColor:[[UIColor lightGrayColor] CGColor]];
[[selectedPhotoButton layer] setShadowOffset: CGSizeMake(1.0f, 1.0f)];
[[selectedPhotoButton layer] setShadowRadius:0.5f];
[[selectedPhotoButton layer] setShadowOpacity:1.0f]; 

// Now add the white border    
[[selectedPhotoButton layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[[selectedPhotoButton layer] setBorderWidth:2.0];

// Now add the X mark subview
UIImage *deleteImage = [UIImage imageNamed:@"nocheck_photo.png"];
UIImageView *deleteMark = [[UIImageView alloc] initWithFrame:CGRectMake(53, -5, 27, 27)];
deleteMark.contentMode = UIViewContentModeScaleAspectFit;
[deleteMark setImage:deleteImage];
[selectedPhotoButton addSubview:deleteMark];
[deleteMark release];

我不明白为什么边框出现在deleteMark子视图的上方。有没有办法获得预期的效果?

谢谢!


不要设置边框,尝试绘制它! - tipycalFlow
@tipycalFlow 怎么了?为什么? - return true
@returntrue 这个问题很老了,但我想我是在寻求控制绘制顺序的方法。 - tipycalFlow
3个回答

18

来自苹果关于CALayer的文档:

边框是从接收器的边界向内进行描绘,它的宽度由borderWidth属性决定。它会在接收器的内容和子图层之上合成,并包括cornerRadius属性的效果。

为了获得您想要的效果,建议将图像放入一个独立的子视图/子图层中,并设置该子图层的borderWidth属性。


抱歉,您能否提供一些伪代码来澄清一下?这个图像正在被设置为UIButton的图像。您的意思是要避免这样做吗? - kurisukun
4
selectedPhotoButtondeleteMark创建一个共同的父视图,即不要将deleteMark作为selectedPhotoButton的子视图添加,而是将它们两个都添加到一个新的UIView中。 - MrMage

5
你可以将图层的zPosition设置为-1。这对我有用。

2

我遇到了类似的问题(我想要防止边框线覆盖在我的子视图上面)。

CAShapeLayer * _border = [CAShapeLayer layer];
_border.strokeColor = [UIColor colorWithRed:119/255.0f green:119/255.0f blue:119/255.0f alpha:1.0f].CGColor;
_border.fillColor = nil;
[bgRoundView.layer addSublayer:_border];
_border.path = [UIBezierPath bezierPathWithRoundedRect:bgRoundView.bounds cornerRadius:20.f].CGPath;

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