UIView只设置边框

有没有办法将UIView的边框设置为一种颜色,并将顶部和底部分开?

不支持CALayer边框不支持这种行为。 最简单的方法来完成你想要的是在你的视图的每一面添加一个n点的不透明的子视图,你所需的边框颜色作为它的背景颜色。

例:

CGSize mainViewSize = theView.bounds.size; CGFloat borderWidth = 2; UIColor *borderColor = [UIColor redColor]; UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, borderWidth, mainViewSize.height)]; UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(mainViewSize.width - borderWidth, 0, borderWidth, mainViewSize.height)]; leftView.opaque = YES; rightView.opaque = YES; leftView.backgroundColor = borderColor; rightView.backgroundColor = borderColor; // for bonus points, set the views' autoresizing mask so they'll stay with the edges: leftView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin; rightView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin; [theView addSubview:leftView]; [theView addSubview:rightView]; [leftView release]; [rightView release]; 

请注意,这不会完全符合CALayer边界的行为 – 左侧和右侧边框视图将始终位于其超级视图的边界内。

像边界一样的视图的答案是非常好的,但请记住,每个视图都是一个耗费大量内存的UI对象。

我将使用uivew的图层在已经存在的UIview上绘制颜色的描边。

 -(CAShapeLayer*)drawLineFromPoint:(CGPoint)fromPoint toPoint:(CGPoint) toPoint withColor:(UIColor *)color andLineWidth:(CGFloat)lineWidth{ CAShapeLayer *lineShape = nil; CGMutablePathRef linePath = nil; linePath = CGPathCreateMutable(); lineShape = [CAShapeLayer layer]; lineShape.lineWidth = lineWidth; lineShape.strokeColor = color.CGColor; NSUInteger x = fromPoint.x; NSUInteger y = fromPoint.y; NSUInteger toX = toPoint.x; NSUInteger toY = toPoint.y; CGPathMoveToPoint(linePath, nil, x, y); CGPathAddLineToPoint(linePath, nil, toX, toY); lineShape.path = linePath; CGPathRelease(linePath); return lineShape;} 

并将其添加到我们的视图。

 CAShapeLayer* borderLine=[self drawLineFromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0,_myView.frame.size.height) withColor:[UIColor lightGrayColor] andLineWidth:1.0f]; [_myView.layer addSublayer:borderLine]; 

所以…我们有一个观点,实际上是从上到下画一条线。 结果是有一条线看起来像是一个像素宽度的边框。

更新了Swift 3.0

我写了一个Swift扩展(用于UIButton),它模拟将UIView的任何一边的边框设置为给定的颜色和宽度。 这与@Noah Witherspoon的方法类似,但是基于自包含和自动布局约束。

  // Swift 3.0 extension UIView { enum Border { case left case right case top case bottom } func setBorder(border: UIView.Border, weight: CGFloat, color: UIColor ) { let lineView = UIView() addSubview(lineView) lineView.backgroundColor = color lineView.translatesAutoresizingMaskIntoConstraints = false switch border { case .left: lineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true lineView.topAnchor.constraint(equalTo: topAnchor).isActive = true lineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true lineView.widthAnchor.constraint(equalToConstant: weight).isActive = true case .right: lineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true lineView.topAnchor.constraint(equalTo: topAnchor).isActive = true lineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true lineView.widthAnchor.constraint(equalToConstant: weight).isActive = true case .top: lineView.topAnchor.constraint(equalTo: topAnchor).isActive = true lineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true lineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true lineView.heightAnchor.constraint(equalToConstant: weight).isActive = true case .bottom: lineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true lineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true lineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true lineView.heightAnchor.constraint(equalToConstant: weight).isActive = true } } } 

这听起来像是两个答案之一:

如果你的视图是一个静态的大小,那么把一个UIView放在它后面,比你的前视图宽2个像素,比它缩短2个像素。

如果它是非静态大小,那么你可以做同样的事情,每当你调整前景视图的大小时调整后台视图的大小,或者实现一个实现UIView的自定义对象,并实现(覆盖)你自己的drawRect例程。

NAUIViewWithBorders为我做了诡计。 另请参阅创作者的SOpost 。 值得检查,如果你需要更多的夫妇观点这个function。

 public extension UIView { // Border type and arbitrary tag values to identify UIView borders as subviews public enum BorderType: Int { case left = 20000 case right = 20001 case top = 20002 case bottom = 20003 } public func addBorder(borderType: BorderType, width: CGFloat, color: UIColor) { // figure out frame and resizing based on border type var autoresizingMask: UIViewAutoresizing var layerFrame: CGRect switch borderType { case .left: layerFrame = CGRect(x: 0, y: 0, width: width, height: self.bounds.height) autoresizingMask = [ .flexibleHeight, .flexibleRightMargin ] case .right: layerFrame = CGRect(x: self.bounds.width - width, y: 0, width: width, height: self.bounds.height) autoresizingMask = [ .flexibleHeight, .flexibleLeftMargin ] case .top: layerFrame = CGRect(x: 0, y: 0, width: self.bounds.width, height: width) autoresizingMask = [ .flexibleWidth, .flexibleBottomMargin ] case .bottom: layerFrame = CGRect(x: 0, y: self.bounds.height - width, width: self.bounds.width, height: width) autoresizingMask = [ .flexibleWidth, .flexibleTopMargin ] } // look for the existing border in subviews var newView: UIView? for eachSubview in self.subviews { if eachSubview.tag == borderType.rawValue { newView = eachSubview break } } // set properties on existing view, or create a new one if newView == nil { newView = UIView(frame: layerFrame) newView?.tag = borderType.rawValue self.addSubview(newView!) } else { newView?.frame = layerFrame } newView?.backgroundColor = color newView?.autoresizingMask = autoresizingMask }