添加边框一个UIView(而不是内部)的外(Add a border outside of a UI

2019-07-20 20:57发布

如果在这样一个视图中使用的代码添加视图的边界

self.layer.borderColor = [UIColor yellowColor].CGColor;
self.layer.borderWidth = 2.0f;

边框是类似下面的视图中添加:

正确的观点是原来的观点,你可以看到,镶上视图的黑色区域是比原来少一个。 但我希望得到的是原来的观点,这样的外边框: 。 黑色的面积等于原来的,我怎么能实现呢?

Answer 1:

不幸的是,不是简单的,你可以设置边框对齐到外面一点点财产。 因为UIViews默认绘图操作其边界内绘制它吸引对准里面。

我想到的最简单的解决办法是通过应用边框时边框宽度的尺寸扩大的UIView:

CGFloat borderWidth = 2.0f;

self.frame = CGRectInset(self.frame, -borderWidth, -borderWidth);
self.layer.borderColor = [UIColor yellowColor].CGColor;
self.layer.borderWidth = borderWidth;


Answer 2:

好了,已经有一个公认的答案,但我认为这是一个更好的方式来做到这一点,你就必须比你的观点来了一个新的层有点大,并且不要将屏蔽对视图的层的边界(实际上是默认行为)。 下面是示例代码:

CALayer * externalBorder = [CALayer layer];
externalBorder.frame = CGRectMake(-1, -1, myView.frame.size.width+2, myView.frame.size.height+2);
externalBorder.borderColor = [UIColor blackColor].CGColor;
externalBorder.borderWidth = 1.0;

[myView.layer addSublayer:externalBorder];
myView.layer.masksToBounds = NO;

当然,这是如果你想你的边界是1个团结大,如果你想要更多的你适应的borderWidth和层的相应的框架。 这比使用第二视图位作为一个更大更好CALayer是比轻UIView和你没有做修改的框架myView ,这是很好的,例如,如果myView是一个UIImageView

注:对我来说,结果是不完美的模拟器(该层是不完全在正确的位置,使该层为一侧较厚有时),但到底是什么要求就实际设备。

编辑

其实我在NB谈论这个问题只是因为我已经减少了模拟器的屏幕上正常大小也绝对没有问题

希望能帮助到你



Answer 3:

通过上述公认的最佳答案我有这样不是很好的结果和难看的边缘制作经验:

因此,我会分享我的UIView 斯威夫特扩展和你在一起,使用一个UIBezierPath代替边境轮廓-没有难看的边缘(灵感@Fattie ):

//  UIView+BezierPathBorder.swift

import UIKit

extension UIView {

    fileprivate var bezierPathIdentifier:String { return "bezierPathBorderLayer" }

    fileprivate var bezierPathBorder:CAShapeLayer? {
        return (self.layer.sublayers?.filter({ (layer) -> Bool in
            return layer.name == self.bezierPathIdentifier && (layer as? CAShapeLayer) != nil
        }) as? [CAShapeLayer])?.first
    }

    func bezierPathBorder(_ color:UIColor = .white, width:CGFloat = 1) {

        var border = self.bezierPathBorder
        let path = UIBezierPath(roundedRect: self.bounds, cornerRadius:self.layer.cornerRadius)
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask

        if (border == nil) {
            border = CAShapeLayer()
            border!.name = self.bezierPathIdentifier
            self.layer.addSublayer(border!)
        }

        border!.frame = self.bounds
        let pathUsingCorrectInsetIfAny =
            UIBezierPath(roundedRect: border!.bounds, cornerRadius:self.layer.cornerRadius)

        border!.path = pathUsingCorrectInsetIfAny.cgPath
        border!.fillColor = UIColor.clear.cgColor
        border!.strokeColor = color.cgColor
        border!.lineWidth = width * 2
    }

    func removeBezierPathBorder() {
        self.layer.mask = nil
        self.bezierPathBorder?.removeFromSuperlayer()
    }

}

例:

let view = UIView(frame: CGRect(x: 20, y: 20, width: 100, height: 100))
view.layer.cornerRadius = view.frame.width / 2
view.backgroundColor = .red

//add white 2 pixel border outline
view.bezierPathBorder(.white, width: 2)

//remove border outline (optional)
view.removeBezierPathBorder()


Answer 4:

那么有没有直接的方法来做到这一点你可以考虑一些解决方法。

  1. 改变和提高帧,并添加BORDERCOLOR像你一样
  2. 添加视图当前视图背后具有较大的大小,使其显示为border.Can为自定义类的视图中工作
  3. 如果你不需要一个明确的边界(皆伐边界),那么你可以依靠阴影为目的

     [view1 setBackgroundColor:[UIColor blackColor]]; UIColor *color = [UIColor yellowColor]; view1.layer.shadowColor = [color CGColor]; view1.layer.shadowRadius = 10.0f; view1.layer.shadowOpacity = 1; view1.layer.shadowOffset = CGSizeZero; view1.layer.masksToBounds = NO; 


Answer 5:

对于斯威夫特的实现,您可以将其添加为一个UIView扩展。

extension UIView {

    struct Constants {
        static let ExternalBorderName = "externalBorder"
    }

    func addExternalBorder(borderWidth: CGFloat = 2.0, borderColor: UIColor = UIColor.whiteColor()) -> CALayer {
        let externalBorder = CALayer()
        externalBorder.frame = CGRectMake(-borderWidth, -borderWidth, frame.size.width + 2 * borderWidth, frame.size.height + 2 * borderWidth)
        externalBorder.borderColor = borderColor.CGColor
        externalBorder.borderWidth = borderWidth
        externalBorder.name = Constants.ExternalBorderName

        layer.insertSublayer(externalBorder, atIndex: 0)
        layer.masksToBounds = false

        return externalBorder
    }

    func removeExternalBorders() {
        layer.sublayers?.filter() { $0.name == Constants.ExternalBorderName }.forEach() {
            $0.removeFromSuperlayer()
        }
    }

    func removeExternalBorder(externalBorder: CALayer) {
        guard externalBorder.name == Constants.ExternalBorderName else { return }
        externalBorder.removeFromSuperlayer()
    }

}


Answer 6:

加入边界之前增加视图的与边框宽度帧的宽度和高度:

float borderWidth = 2.0f
CGRect frame = self.frame;
frame.width += borderWidth;
frame.height += borderWidth;
 self.layer.borderColor = [UIColor yellowColor].CGColor;
 self.layer.borderWidth = 2.0f;


Answer 7:

其实有一个非常简单的解决方案。 只需设置他们两个这样的:

view.layer.borderWidth = 5

view.layer.borderColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5).cgColor

view.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.25).cgColor


Answer 8:

我喜欢@picciano的解决方案,如果你想爆炸圆的而不是方将其替换addExternalBorder功能:

func addExternalBorder(borderWidth: CGFloat = 2.0, borderColor: UIColor = UIColor.white) {
        let externalBorder = CALayer()
        externalBorder.frame = CGRect(x: -borderWidth, y: -borderWidth, width: frame.size.width + 2 * borderWidth, height: frame.size.height + 2 * borderWidth)
        externalBorder.borderColor = borderColor.cgColor
        externalBorder.borderWidth = borderWidth
        externalBorder.cornerRadius = (frame.size.width + 2 * borderWidth) / 2
        externalBorder.name = Constants.ExternalBorderName
        layer.insertSublayer(externalBorder, at: 0)
        layer.masksToBounds = false

    }


Answer 9:

我喜欢@picciano&@Maksim Kniazev的解决方案。 我们也可以创建环形边框与以下内容:

func addExternalAnnularBorder(borderWidth: CGFloat = 2.0, borderColor: UIColor = UIColor.white) {
    let externalBorder = CALayer()
    externalBorder.frame = CGRect(x: -borderWidth*2, y: -borderWidth*2, width: frame.size.width + 4 * borderWidth, height: frame.size.height + 4 * borderWidth)
    externalBorder.borderColor = borderColor.cgColor
    externalBorder.borderWidth = borderWidth
    externalBorder.cornerRadius = (frame.size.width + 4 * borderWidth) / 2
    externalBorder.name = Constants.ExternalBorderName
    layer.insertSublayer(externalBorder, at: 0)
    layer.masksToBounds = false
}


文章来源: Add a border outside of a UIView (instead of inside)