在UIView之外添加边框(而不是在里面)

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

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

边框被添加到视图中,如下所示: 在这里输入图像说明

正确的视angular就是原始的视angular,正如你所看到的,边界视图的黑色区域比原来的小。 但是我想得到的是原始视图之外的边框,就像这样: 在这里输入图像说明 。 黑色的面积和原来的一样,我该怎么实现呢?

不幸的是,你可以设置一个小小的属性来把边框与外部alignment。 它绘制在内部alignment,因为UIViews默认绘图操作在其范围内绘制。

想到的最简单的解决scheme是在应用边框时将UIView扩展为边框宽度的大小:

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

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

  1. 改变和增加框架,并像你一样添加bordercolor
  2. 在当前视图后面添加一个视图,使其显示为边框。可以作为自定义视图类别工作
  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; 

好吧,已经有了一个可以接受的答案,但我认为有一个更好的方法来实现它,你只需要有一个比你的视图大一点的新图层,而不是把它隐藏到视图图层的边界默认行为)。 这里是示例代码:

 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和相应的图层的框架。 这比使用第二个视图更好一点,因为CALayerUIView更轻,而且您还没有修改myView的框架,如果myViewUIImageView

注意:对于我来说,模拟器上的结果并不完美(层不完全在正确的位置,所以有时层的厚度有时会变厚),但是在真实的设备上正是要求的。

编辑

其实我在NB上谈论的问题只是因为我减less了模拟器的屏幕,正常的大小是绝对没有问题

希望能帮助到你

对于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 == Constants.ExternalBorderName else { return } externalBorder.removeFromSuperlayer() } } 

在添加边框之前,用边框宽度增加视图框架的宽度和高度:

 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; 

有了上面接受的最好的答案,我做了这样不好的结果和难看的边缘的经验:

边界没有贝塞尔路径

所以我会和你一起分享我的UIView Swift扩展,它使用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()