在UIView外部添加边框(而不是在内部)

rem*_*its 80 border uiview ios

如果使用视图中的代码添加视图的边框

self.layer.borderColor = [UIColor yellowColor].CGColor;
self.layer.borderWidth = 2.0f;
Run Code Online (Sandbox Code Playgroud)

边框添加到视图内部,如下所示: 在此输入图像描述

右视图是原始视图,如您所见,边界视图的黑色区域小于原始视图.但我想得到的是原始视图之外的边框,如下所示:在此输入图像描述.黑色区域等于原始区域,我该如何实现呢?

Ell*_*rry 97

不幸的是,您可以设置一个小的属性来将边框与外部对齐.它绘制与内部对齐,因为UIViews默认绘制操作在其边界内绘制.

想到的最简单的解决方案是在应用边框时按边框宽度的大小扩展UIView:

CGFloat borderWidth = 2.0f;

self.frame = CGRectInset(self.frame, -borderWidth, -borderWidth);
self.layer.borderColor = [UIColor yellowColor].CGColor;
self.layer.borderWidth = borderWidth;
Run Code Online (Sandbox Code Playgroud)

  • 在Swift中尝试了这个解决方案,不幸的是,边框不断在UIImageView中绘制 (3认同)

Hug*_*ier 21

好的,已经有一个已接受的答案,但我认为有一个更好的方法,你只需要一个比你的视图大一点的新图层,不要将它掩盖到视图层的边界(实际上是默认行为).以下是示例代码:

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;
Run Code Online (Sandbox Code Playgroud)

当然,如果你想要你的边框大于1个整数,如果你想要更多,你可以相应地调整borderWidth图层和框架.这比使用稍大一点的第二个视图更好,因为a CALayer比a轻UIView,你没有修改框架myView,这很好,例如,如果myViewUIImageView

注意:对我来说,结果在模拟器上并不完美(图层并不完全在正确的位置,因此有时候一侧的图层厚一些),但这正是真实设备上的要求.

编辑

实际上我在NB中谈到的问题只是因为我减少了模拟器的屏幕,在正常尺寸上绝对没有问题

希望能帮助到你

  • myView.layer.masksToBounds = NO; 当myView具有CornerRadius时,这会产生问题。 (2认同)

Pet*_*inz 19

通过以上公认的最佳答案,我使用了不太好的结果和难看的边缘经验:

没有bezier路径的边界

所以我将与你分享我的UIView Swift扩展,它使用UIBezierPath作为边框轮廓 - 没有难看的边缘(灵感来自@Fattie):

边界与bezier路径

//  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()
    }

}
Run Code Online (Sandbox Code Playgroud)

例:

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()
Run Code Online (Sandbox Code Playgroud)


pic*_*ano 14

对于Swift实现,您可以将其添加为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()
    }

}
Run Code Online (Sandbox Code Playgroud)


Lit*_*T.V 13

那么没有直接的方法来做它你可以考虑一些解决方法.

  1. 更改并增加框架并添加bordercolor
  2. 在当前视图后面添加一个较大的视图,使其显示为border.可以作为自定义视图类
  3. 如果你不需要一个明确的边界(clearcut border),那么你可以依靠阴影来达到目的

    [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;
    
    Run Code Online (Sandbox Code Playgroud)


Ond*_*j H 6

雨燕5

extension UIView {
    fileprivate struct Constants {
        static let externalBorderName = "externalBorder"
    }

    func addExternalBorder(borderWidth: CGFloat = 2.0, borderColor: UIColor = UIColor.white) -> CALayer {
        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.name = Constants.ExternalBorderName

        layer.insertSublayer(externalBorder, at: 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()
    }
}
Run Code Online (Sandbox Code Playgroud)