父视图边框剪切了子视图

4
我希望这个子视图能够超出其父视图,但是父视图的边框会切割子视图。有没有办法防止这种情况发生?

示例

class TheView : UIView {

    let theSubView = UIButton()


    override init(frame: CGRect) {
        super.init(frame: frame)

        layer.borderColor = UIColor.gray.cgColor
        layer.borderWidth = 1
        clipsToBounds = false

        addSubview(theSubView)

        theSubView.backgroundColor = UIColor.green
        theSubView.frame = CGRect(x: 0, y: -10, width: 50, height: 50)
    }   
}

哦,你的意思是让灰色边框被绿色正方形遮盖住? - Fogmeister
是的,没错。 - Dru Lang
有趣的是,在调试视图层次结构中,边框显示在子视图下方。 - Victor Engel
5个回答

9
您不能使视图自己的边框出现在子视图的内容下面。例如,在CALayer borderWidth参考文献中有记录:

它位于接收器的内容和子层之上...

解决方法之一是添加一个单独的子视图来绘制边框,并将绘制边框的视图放置在按钮下方。示例:
@IBDesignable
class TheView : UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    private let borderView = UIView()
    private let button = UIButton()

    private func commonInit() {
        borderView.layer.borderColor = UIColor.gray.cgColor
        borderView.layer.borderWidth = 1
        borderView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        borderView.frame = bounds
        addSubview(borderView)

        button.backgroundColor = UIColor.green
        button.frame = CGRect(x: 0, y: -10, width: 50, height: 50)
        addSubview(button)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

}

结果:

结果截图


3

不要使用视图层的边框,自己绘制边框:

class TheView : UIView {

    let theSubView = UIButton()

    override func draw(_ rect: CGRect) {
        UIColor.gray.set()
        UIBezierPath(rect: rect).stroke()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        clipsToBounds = false
        isOpaque = false

        addSubview(theSubView)

        theSubView.backgroundColor = UIColor.green
        theSubView.frame = CGRect(x: 0, y: -10, width: 50, height: 50)
    }   

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

enter image description here


1
您可能还想设置 contentMode = .redraw - rob mayoff

0
我也在解决这个问题。即使边框有圆角,这里有一个解决方案。
将函数添加到UIView的子类中:
- (void)addBorderWithRoundedCorners:(UIRectCorner)corner
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];
    CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
    borderLayer.path  = maskPath.CGPath;
    borderLayer.lineWidth   = 1.0f;
    borderLayer.strokeColor = mainColor.CGColor;
    borderLayer.fillColor   = [UIColor clearColor].CGColor;
    borderLayer.frame = self.bounds;

    self.layer.mask = borderLayer;
    [self.layer addSublayer:borderLayer];
}

并从awakeFromNib调用此函数:

[self addBorderWithRoundedCorners:UIRectCornerAllCorners];

0

我认为重新设计视图的结构会更好,这样theView就不需要担心其边界外的内容了。
例如,您可以将更大和更小的矩形都作为子视图。然后将较小的矩形放在较大的矩形上方。这样它应该能够覆盖边框线。


0
如果您将另一个视图作为参考,使得您的两个视图现在具有相同的状态(作为另一个视图的子视图),那么您可以重叠它们,包括它们的框架。您可以使用以下代码选择哪个子视图应该在前面:
myNewView.insertSubview(myWhiteViewWithBorder, at: 0)
myNewView.insertSubview(myGreenView, at: 1)

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