Cómo agregar un borde justo en la parte superior de una UIView

Mi pregunta es sobre el título.

No sé cómo agregar un borde en un lado específico, superior o inferior, en cualquier lado … layer.border dibuja el borde de toda la vista …

Considero la posibilidad de subclasificar UIView y reemplazar el exceso de UIView aquí. ¿Por qué no agregar una extensión en UIView y agregar subvistas de borde?

 @discardableResult func addBorders(edges: UIRectEdge, color: UIColor, inset: CGFloat = 0.0, thickness: CGFloat = 1.0) -> [UIView] { var borders = [UIView]() @discardableResult func addBorder(formats: String...) -> UIView { let border = UIView(frame: .zero) border.backgroundColor = color border.translatesAutoresizingMaskIntoConstraints = false addSubview(border) addConstraints(formats.flatMap { NSLayoutConstraint.constraints(withVisualFormat: $0, options: [], metrics: ["inset": inset, "thickness": thickness], views: ["border": border]) }) borders.append(border) return border } if edges.contains(.top) || edges.contains(.all) { addBorder(formats: "V:|-0-[border(==thickness)]", "H:|-inset-[border]-inset-|") } if edges.contains(.bottom) || edges.contains(.all) { addBorder(formats: "V:[border(==thickness)]-0-|", "H:|-inset-[border]-inset-|") } if edges.contains(.left) || edges.contains(.all) { addBorder(formats: "V:|-inset-[border]-inset-|", "H:|-0-[border(==thickness)]") } if edges.contains(.right) || edges.contains(.all) { addBorder(formats: "V:|-inset-[border]-inset-|", "H:[border(==thickness)]-0-|") } return borders } // Usage: view.addBorder(edges: [.all]) // All with default arguments view.addBorder(edges: [.top], color: .green) // Just Top, green, default thickness view.addBorder(edges: [.left, .right, .bottom], color: .red, thickness: 3) // All except Top, red, thickness 3 

Con este código no estás vinculado a tu subclase también, puedes aplicarlo a cualquier cosa y todo lo que hereda de UIView : reutilizable en tu proyecto y en cualquier otro. Pase otros argumentos a sus métodos para definir otros colores y anchos. Muchas opciones.

Versión Swift de la impresionante adición de Adam Waite 5/5/15 :

 extension CALayer { func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { var border = CALayer() switch edge { case .Top: border.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), thickness) break case .Bottom: border.frame = CGRectMake(0, CGRectGetHeight(self.frame) - thickness, CGRectGetWidth(self.frame), thickness) break case .Left: border.frame = CGRectMake(0, 0, thickness, CGRectGetHeight(self.frame)) break case .Right: border.frame = CGRectMake(CGRectGetWidth(self.frame) - thickness, 0, thickness, CGRectGetHeight(self.frame)) break default: break } border.backgroundColor = color.CGColor; addSublayer(border) } } 

Swift 3:

 extension CALayer { func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { let border = CALayer() switch edge { case .top: border.frame = CGRect(x: 0, y: 0, width: frame.width, height: thickness) case .bottom: border.frame = CGRect(x: 0, y: frame.height - thickness, width: frame.width, height: thickness) case .left: border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.height) case .right: border.frame = CGRect(x: frame.width - thickness, y: 0, width: thickness, height: frame.height) default: break } border.backgroundColor = color.cgColor; addSublayer(border) } } 

La mejor manera para mí es una categoría en UIView, pero agregando vistas en lugar de CALayers, para que podamos aprovechar AutoresizingMasks para asegurarnos de que las fronteras cambian de tamaño junto con la supervista.

 - (void)addTopBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth { UIView *border = [UIView new]; border.backgroundColor = color; [border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin]; border.frame = CGRectMake(0, 0, self.frame.size.width, borderWidth); [self addSubview:border]; } - (void)addBottomBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth { UIView *border = [UIView new]; border.backgroundColor = color; [border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin]; border.frame = CGRectMake(0, self.frame.size.height - borderWidth, self.frame.size.width, borderWidth); [self addSubview:border]; } - (void)addLeftBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth { UIView *border = [UIView new]; border.backgroundColor = color; border.frame = CGRectMake(0, 0, borderWidth, self.frame.size.height); [border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin]; [self addSubview:border]; } - (void)addRightBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth { UIView *border = [UIView new]; border.backgroundColor = color; [border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin]; border.frame = CGRectMake(self.frame.size.width - borderWidth, 0, borderWidth, self.frame.size.height); [self addSubview:border]; } 

Código para la respuesta seleccionada, en caso de que alguien lo quiera.

NOTA: Esto no funciona con autolayout (también conocido como, girar el dispositivo a horizontal, etc.).

Primero defina un espesor:

 NSInteger borderThickness = 1; 

Luego, simplemente copie el uso de alguno o todos para establecer el borde que desea establecer.

Borde superior

 UIView *topBorder = [UIView new]; topBorder.backgroundColor = [UIColor lightGrayColor]; topBorder.frame = CGRectMake(0, 0, myView.frame.size.width, borderThickness); [myView addSubview:topBorder]; 

Borde inferior

 UIView *bottomBorder = [UIView new]; bottomBorder.backgroundColor = [UIColor lightGrayColor]; bottomBorder.frame = CGRectMake(0, myView.frame.size.height - borderThickness, myView.frame.size.width, borderThickness); [myView addSubview:bottomBorder]; 

Frontera izquierda

 UIView *leftBorder = [UIView new]; leftBorder.backgroundColor = [UIColor lightGrayColor]; leftBorder.frame = CGRectMake(0, 0, borderThickness, myView.frame.size.height); [myView addSubview:leftBorder]; 

Borde derecho

 UIView *rightBorder = [UIView new]; rightBorder.backgroundColor = [UIColor lightGrayColor]; rightBorder.frame = CGRectMake(myView.frame.size.width - borderThickness, 0, borderThickness, myView.frame.size.height); [myView addSubview:rightBorder]; 

Subclase UIView e implementar drawRect: en su subclase, por ejemplo:

C objective

 - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect)); CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor] ); CGContextSetLineWidth(context, 2.0); CGContextStrokePath(context); } 

Swift 4

 override func draw(_ rect: CGRect) { let cgContext = UIGraphicsGetCurrentContext() cgContext?.move(to: CGPoint(x: rect.minX, y: rect.minY)) cgContext?.addLine(to: CGPoint(x: rect.maxX, y: rect.minY)) cgContext?.setStrokeColor(UIColor.red.cgColor) cgContext?.setLineWidth(2.0) cgContext?.strokePath() } 

Esto dibuja una línea roja de 2 píxeles como borde superior. Todas las demás variaciones que menciona se dejan como un ejercicio trivial para el lector.

Se recomienda la Guía de progtwigción 2D de cuarzo .

Swift 3.0

Swift 4.1

 extension CALayer { func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { let border = CALayer(); switch edge { case UIRectEdge.top: border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness) break case UIRectEdge.bottom: border.frame = CGRect(x:0, y:self.frame.height - thickness, width:self.frame.width, height:thickness) break case UIRectEdge.left: border.frame = CGRect(x:0, y:0, width: thickness, height: self.frame.height) break case UIRectEdge.right: border.frame = CGRect(x:self.frame.width - thickness, y: 0, width: thickness, height:self.frame.height) break default: break } border.backgroundColor = color.cgColor; self.addSublayer(border) } } 

Versión Swift:

 var myView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) myView.backgroundColor = UIColor.yellowColor() var border = CALayer() border.backgroundColor = UIColor.lightGrayColor() border.frame = CGRect(x: 0, y: 0, width: myView.frame.width, height: 0.5) myView.layer.addSublayer(border) 

Editar: para ver las versiones actualizadas, consulte mi repository aquí: https://github.com/goktugyil/EZSwiftExtensions/blob/master/Sources/UIViewExtensions.swift

Mira las partes addBorder

Pregunta anterior, pero aún falta la solución de autodiseño con los ajustes del borde del tiempo de ejecución.

 borders(for: [.left, .bottom], width: 2, color: .red) 

La siguiente extensión UIView agregará el borde solo en los bordes dados. Si cambia los bordes en el tiempo de ejecución, los bordes se ajustarán en consecuencia.

 extension UIView { func borders(for edges:[UIRectEdge], width:CGFloat = 1, color: UIColor = .black) { if edges.contains(.all) { layer.borderWidth = width layer.borderColor = color.cgColor } else { let allSpecificBorders:[UIRectEdge] = [.top, .bottom, .left, .right] for edge in allSpecificBorders { if let v = viewWithTag(Int(edge.rawValue)) { v.removeFromSuperview() } if edges.contains(edge) { let v = UIView() v.tag = Int(edge.rawValue) v.backgroundColor = color v.translatesAutoresizingMaskIntoConstraints = false addSubview(v) var horizontalVisualFormat = "H:" var verticalVisualFormat = "V:" switch edge { case UIRectEdge.bottom: horizontalVisualFormat += "|-(0)-[v]-(0)-|" verticalVisualFormat += "[v(\(width))]-(0)-|" case UIRectEdge.top: horizontalVisualFormat += "|-(0)-[v]-(0)-|" verticalVisualFormat += "|-(0)-[v(\(width))]" case UIRectEdge.left: horizontalVisualFormat += "|-(0)-[v(\(width))]" verticalVisualFormat += "|-(0)-[v]-(0)-|" case UIRectEdge.right: horizontalVisualFormat += "[v(\(width))]-(0)-|" verticalVisualFormat += "|-(0)-[v]-(0)-|" default: break } self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: horizontalVisualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["v": v])) self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: verticalVisualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["v": v])) } } } } } 

Tomé las respuestas de Adam Waite y Pauls y las combiné. También agregué la posibilidad de canalizar los bordes seleccionados juntos, por lo que necesita llamar solo a una función como esta:

 [self.view addBordersToEdge:(UIRectEdgeLeft|UIRectEdgeRight) withColor:[UIColor grayColor] andWidth:1.0]; 

más o menos:

 [self.view addBordersToEdge:(UIRectEdgeAll) withColor:[UIColor grayColor] andWidth:1.0]; 

Lo que necesita implementar es una categoría en UIView como se sugiere en otras respuestas con la siguiente implementación:

 - (void)addBordersToEdge:(UIRectEdge)edge withColor:(UIColor *)color andWidth:(CGFloat) borderWidth { if (edge & UIRectEdgeTop) { UIView *border = [UIView new]; border.backgroundColor = color; [border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin]; border.frame = CGRectMake(0, 0, self.frame.size.width, borderWidth); [self addSubview:border]; } if (edge & UIRectEdgeLeft) { UIView *border = [UIView new]; border.backgroundColor = color; border.frame = CGRectMake(0, 0, borderWidth, self.frame.size.height); [border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin]; [self addSubview:border]; } if (edge & UIRectEdgeBottom) { UIView *border = [UIView new]; border.backgroundColor = color; [border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin]; border.frame = CGRectMake(0, self.frame.size.height - borderWidth, self.frame.size.width, borderWidth); [self addSubview:border]; } if (edge & UIRectEdgeRight) { UIView *border = [UIView new]; border.backgroundColor = color; [border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin]; border.frame = CGRectMake(self.frame.size.width - borderWidth, 0, borderWidth, self.frame.size.height); [self addSubview:border]; } } 

Aquí hay una solución simple. Agregue una etiqueta a su UIView, borre el texto en la etiqueta y establezca el color de fondo de la etiqueta para que sea su color de borde. Establezca el origen (x, y) de su etiqueta para que sea el origen (x, y) de su vista. y configure el ancho de la etiqueta para que sea el ancho de su UIView, configure la altura para que sea 1 o 2 (para la altura de su borde en la parte superior de su UIView). Y eso debería hacer el truco.

// MARK: – Añadir LeftBorder para ver

 (void)prefix_addLeftBorder:(UIView *) viewName { CALayer *leftBorder = [CALayer layer]; leftBorder.backgroundColor = [UIColor colorWithRed:221/255.0f green:221/255.0f blue:221/255.0f alpha:1.0f].CGColor; leftBorder.frame = CGRectMake(0,0,1.0,viewName.frame.size.height); [viewName.layer addSublayer:leftBorder]; } 

// MARK: – Agregar RightBorder para ver

 (void)prefix_addRightBorder:(UIView *) viewName { CALayer *rightBorder = [CALayer layer]; rightBorder.backgroundColor = [UIColor colorWithRed:221/255.0f green:221/255.0f blue:221/255.0f alpha:1.0f].CGColor; rightBorder.frame = CGRectMake(viewName.frame.size.width - 1.0,0,1.0,viewName.frame.size.height); [viewName.layer addSublayer:rightBorder]; } 

// MARCA: – Añadir borde inferior para ver

 (void)prefix_addbottomBorder:(UIView *) viewName { CALayer *bottomBorder = [CALayer layer]; bottomBorder.backgroundColor = [UIColor colorWithRed:221/255.0f green:221/255.0f blue:221/255.0f alpha:1.0f].CGColor; bottomBorder.frame = CGRectMake(0,viewName.frame.size.height - 1.0,viewName.frame.size.width,1.0); [viewName.layer addSublayer:bottomBorder]; } 

Partiendo de la respuesta de NSBum , tomé un enfoque similar y creé esta simple subclase de UIView para que funcione en Interface Builder y funcione con restricciones: github link
Al usar CGContextFillRect en lugar de CGContextStrokePath, pude predecir que las líneas permanecen sólidas y dentro de los límites de la vista.

Aquí está la publicación de mi blog sobre esto: http://natrosoft.com/?p=55

– Básicamente solo ingrese una UIView en Interface Builder y cambie su tipo de clase a NAUIViewWithBorders.
– Entonces, en su viewCidLoad de su VC, haga algo como:

 /* For a top border only ———————————————- */ self.myBorderView.borderColorTop = [UIColor redColor]; self.myBorderView..borderWidthsAll = 1.0f; /* For borders with different colors and widths ————————— */ self.myBorderView.borderWidths = UIEdgeInsetsMake(2.0, 4.0, 6.0, 8.0); self.myBorderView.borderColorTop = [UIColor blueColor]; self.myBorderView.borderColorRight = [UIColor redColor]; self.myBorderView.borderColorBottom = [UIColor greenColor]; self.myBorderView.borderColorLeft = [UIColor darkGrayColor]; 

Aquí hay un enlace directo al archivo .m para que pueda ver la implementación. También hay un proyecto de demostración. Espero que esto ayude a alguien 🙂

Mi respuesta a una pregunta similar: https://stackoverflow.com/a/27141956/435766 Personalmente prefiero ir por la ruta de la categoría en esa, ya que quiero poder usarla en cualquier subclase de UIView.

Hice algunos cambios en la respuesta de Dan para poder agregar bordes a múltiples bordes con un solo comando:

 infoView.addBorder(toEdges: [.left, .bottom, .right], color: borderColor, thickness: 1) 

Aquí está el código completo:

 extension UIView { func addBorder(toEdges edges: UIRectEdge, color: UIColor, thickness: CGFloat) { func addBorder(toEdge edges: UIRectEdge, color: UIColor, thickness: CGFloat) { let border = CALayer() border.backgroundColor = color.cgColor switch edges { case .top: border.frame = CGRect(x: 0, y: 0, width: frame.width, height: thickness) case .bottom: border.frame = CGRect(x: 0, y: frame.height - thickness, width: frame.width, height: thickness) case .left: border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.height) case .right: border.frame = CGRect(x: frame.width - thickness, y: 0, width: thickness, height: frame.height) default: break } layer.addSublayer(border) } if edges.contains(.top) || edges.contains(.all) { addBorder(toEdge: .top, color: color, thickness: thickness) } if edges.contains(.bottom) || edges.contains(.all) { addBorder(toEdge: .bottom, color: color, thickness: thickness) } if edges.contains(.left) || edges.contains(.all) { addBorder(toEdge: .left, color: color, thickness: thickness) } if edges.contains(.right) || edges.contains(.all) { addBorder(toEdge: .right, color: color, thickness: thickness) } } } 

Si estoy comstackndo desde el guión gráfico, prefiero agregar una UIView detrás de mi útil UIView … Si quiero crear un borde en la parte superior de mi UIView, simplemente aumento la altura del fondo UIView por el ancho de mi borde. Lo mismo se puede hacer por cualquier otro lado 🙂

Solo publicando aquí para ayudar a alguien que busca agregar bordes. He hecho algunos cambios en la respuesta aceptada aquí etiqueta rápida solo borde izquierda . Ancho cambiado en caso de UIRectEdge.Top desde CGRectGetHeight(self.frame) a CGRectGetWidth(self.frame) y en el caso UIRectEdge.Bottom desde UIScreen.mainScreen().bounds.width a CGRectGetWidth(self.frame) para obtener bordes correctamente. Usando Swift 2.

Finalmente la extensión es:

 extension CALayer { func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { let border = CALayer(); switch edge { case UIRectEdge.Top: border.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), thickness); break case UIRectEdge.Bottom: border.frame = CGRectMake(0, CGRectGetHeight(self.frame) - thickness, CGRectGetWidth(self.frame), thickness) break case UIRectEdge.Left: border.frame = CGRectMake(0, 0, thickness, CGRectGetHeight(self.frame)) break case UIRectEdge.Right: border.frame = CGRectMake(CGRectGetWidth(self.frame) - thickness, 0, thickness, CGRectGetHeight(self.frame)) break default: break } border.backgroundColor = color.CGColor; self.addSublayer(border) } } 

En caso de que alguien necesite alguna vez la versión de Xamarin:

 public static class UIUtils { public static void AddBorder(this CALayer cALayer, UIRectEdge edge, UIColor color, float thickness) { var border = new CALayer(); switch (edge) { case UIRectEdge.Top: border.Frame = new CGRect(0, 0, cALayer.Frame.Width, height: thickness); break; case UIRectEdge.Bottom: border.Frame = new CGRect(0, cALayer.Frame.Height - thickness, width: cALayer.Frame.Width, height: thickness); break; case UIRectEdge.Left: border.Frame = new CGRect(0, 0, width: thickness, height: cALayer.Frame.Height); break; case UIRectEdge.Right: border.Frame = new CGRect(cALayer.Frame.Width - thickness, y: 0, width: thickness, height: cALayer.Frame.Height); break; default: break; } border.BackgroundColor = color.CGColor; cALayer.AddSublayer(border); } } 

Aquí hay una versión de Swift 4 de la respuesta de Pauls

 func addTopBorder(color: UIColor, thickness: CGFloat) { let border = UIView() border.backgroundColor = color border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin] border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: thickness) addSubview(border) } func addBottomBorder(color: UIColor, thickness: CGFloat) { let border = UIView() border.backgroundColor = color border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin] border.frame = CGRect(x: 0, y: frame.size.height - thickness, width: frame.size.width, height: thickness) addSubview(border) } func addLeftBorder(color: UIColor, thickness: CGFloat) { let border = UIView() border.backgroundColor = color border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin] border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.size.height) addSubview(border) } func addRightBorder(color: UIColor, thickness: CGFloat) { let border = UIView() border.backgroundColor = color border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin] border.frame = CGRect(x: frame.size.width - thickness, y: 0, width: thickness, height: frame.size.height) addSubview(border) } 

Personalmente, me gusta la subclasificación de la vista + drawRect, pero esta es solo otra forma de hacerlo (y funciona de la misma manera que la respuesta aceptada por @If Pollavith):

Su nueva capa de borde puede configurarse para tener las dimensiones que desee. Entonces, al igual que la respuesta de @If Pollavith, creas una capa para que sea tan alta como quieras, y tan ancha como la vista que deseas que haya bordeado. Utilice la definición de ttwig de la capa para colocarla donde desee y, a continuación, agréguela como una subcapa a su vista.

Como referencia, mi propio requisito era poner un borde en el lado IZQUIERDO de la vista (por favor, no corte y pegue este código y elimínelo solo porque no pone un borde en la parte superior de la vista – modificar el código a continuación es bastante simple):

  CALayer *leftBorder = [CALayer layer]; leftBorder.borderColor = [UIColor colorWithRed:0.0 green:91.0/255.0 blue:141.0/255.0 alpha:1.0].CGColor; leftBorder.borderWidth = 1; leftBorder.frame = CGRectMake(0, 0, 1.0, CGRectGetHeight(self.myTargetView.frame)); [self.myTargetView.layer addSublayer:leftBorder]; 

Supongo que el único beneficio moderado sobre esto y hacer una pequeña UIView o UILabel es que el CALayer es supuestamente ‘más ligero’, y hay muchos puntos de vista interesantes (como en las opiniones) sobre el exceso de drawRect versus el uso de CALayers (como aquí : iOS: utilizando ‘drawRect:’ de UIView frente a la capa de ‘delaware’ de capas: inContext: ‘ ).

Animal451

Me gusta el color azul.

Además de n8tr puede agregar que hay una disponibilidad para configurarlos desde el guión gráfico:
– agregue dos propiedades como borderColor y borderWidth en el archivo .h;
– entonces puedes agregar keyPaths en el guión gráfico, ver el enlace a la captura de pantalla

Convierta la respuesta DanShev a Swift 3

 extension CALayer { func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) { let border = CALayer() switch edge { case .top: border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness) break case .bottom: border.frame = CGRect(x: 0, y: self.frame.height - thickness, width: self.frame.width, height: thickness) break case .left: border.frame = CGRect(x: 0, y: 0, width: thickness, height: self.frame.height) break case .right: border.frame = CGRect(x: self.frame.width - thickness, y: 0, width: thickness, height: self.frame.height) break default: break } border.backgroundColor = color.cgColor; self.addSublayer(border) } } 

Para Xamarin en C #, simplemente creo el borde en línea al agregar la capa secundaria

  View.Layer.AddSublayer(new CALayer() { BackgroundColor = UIColor.Black.CGColor, Frame = new CGRect(0, 0, View.Frame.Width, 0.5f) }); 

Puede organizar esto (como lo sugirieron otros) para los bordes inferior, izquierdo y derecho.

También puede consultar esta colección de categorías de UIKit y Foundation: https://github.com/leszek-s/LSCategories

Permite agregar bordes en un lado de UIView con una sola línea de código:

 [self.someView lsAddBorderOnEdge:UIRectEdgeTop color:[UIColor blueColor] width:2]; 

y maneja apropiadamente la rotación de vistas mientras que la mayoría de las respuestas publicadas aquí no lo manejan bien.

Nota: la mayoría de las soluciones aquí no son adaptativas y no cambiarán de tamaño. Las soluciones que cambiarán el tamaño tendrán un impacto masivo en su tiempo de inicio ya que usan mucha CPU.

Puedes usar esta solución debajo. Funciona en UIBezierPaths que son más livianos que las capas, lo que provoca tiempos de inicio rápidos. Es fácil de usar, mira las instrucciones a continuación.

 class ResizeBorderView: UIView { var color = UIColor.white var lineWidth: CGFloat = 1 var edges = [UIRectEdge](){ didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { if edges.contains(.top) || edges.contains(.all){ let path = UIBezierPath() path.lineWidth = lineWidth color.setStroke() UIColor.blue.setFill() path.move(to: CGPoint(x: 0, y: 0 + lineWidth / 2)) path.addLine(to: CGPoint(x: self.bounds.width, y: 0 + lineWidth / 2)) path.stroke() } if edges.contains(.bottom) || edges.contains(.all){ let path = UIBezierPath() path.lineWidth = lineWidth color.setStroke() UIColor.blue.setFill() path.move(to: CGPoint(x: 0, y: self.bounds.height - lineWidth / 2)) path.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - lineWidth / 2)) path.stroke() } if edges.contains(.left) || edges.contains(.all){ let path = UIBezierPath() path.lineWidth = lineWidth color.setStroke() UIColor.blue.setFill() path.move(to: CGPoint(x: 0 + lineWidth / 2, y: 0)) path.addLine(to: CGPoint(x: 0 + lineWidth / 2, y: self.bounds.height)) path.stroke() } if edges.contains(.right) || edges.contains(.all){ let path = UIBezierPath() path.lineWidth = lineWidth color.setStroke() UIColor.blue.setFill() path.move(to: CGPoint(x: self.bounds.width - lineWidth / 2, y: 0)) path.addLine(to: CGPoint(x: self.bounds.width - lineWidth / 2, y: self.bounds.height)) path.stroke() } } } 
  1. Establezca la clase de UIView en ResizeBorderView
  2. Establezca el color y el ancho de línea usando yourview.color y yourview.lineWidth en su método viewDidAppear
  3. Establezca los bordes, por ejemplo: yourview.edges = [.right, .left] ([.all]) para todos
  4. Disfrute de inicio rápido y redimensionamiento de bordes

Para establecer Borde superior e inferior para un UIView en Swift.

 let topBorder = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 1)) topBorder.backgroundColor = UIColor.black myView.addSubview(topBorder) let bottomBorder = UIView(frame: CGRect(x: 0, y: myView.frame.size.height - 1, width: 10, height: 1)) bottomBorder.backgroundColor = UIColor.black myView.addSubview(bottomBorder) 

En Swift 4 y 3

 let borderThickness = 2 let topBorder = UIView() topBorder.backgroundColor = UIColor.red topBorder.frame = CGRect(x: 0, y: 0, width: Int(yourViewFromOutlet.frame.size.width), height: borderThickness) yourViewFromOutlet.addSubview(topBorder) 

Se me ocurrió una solución usando Swift 4.1 que usa AutoLayout y UIViews para que cambie de tamaño con la vista.

Se basa en la respuesta de @AdamWaite pero resuelve el problema para las celdas de la vista de tabla donde se reutilizan las celdas. Si no se elimina el borde anterior antes de agregar uno nuevo, la celda reutilizada contendrá múltiples bordes.

Esto se resuelve creando una clase ficticia BorderView y buscando en la subvista los bordes y eliminándolos.

Este código usa SnapKit para las restricciones y CocoaLumberjack para la depuración. Si no los usa, entonces debería ser bastante sencillo convertir

 class BorderView: UIView { } extension UIView { private func addSidedBorder(toEdge edge: UIRectEdge, withColor color: UIColor, inset: CGFloat, thickness: CGFloat) { let border = BorderView(frame: .zero) border.backgroundColor = color addSubview(border) border.snp.makeConstraints { make in switch edge { case .top: make.top.equalToSuperview() make.height.equalTo(thickness) make.left.right.equalToSuperview().inset(inset) case .left: make.left.equalToSuperview() make.width.equalTo(thickness) make.top.bottom.equalToSuperview().inset(inset) case .bottom: make.bottom.equalToSuperview() make.height.equalTo(thickness) make.left.right.equalToSuperview().inset(inset) case .right: make.right.equalToSuperview() make.width.equalTo(thickness) make.top.bottom.equalToSuperview().inset(inset) default: DDLogWarn("Invalid sided border given in ExtendedUIView, border not added correctly") } } } func addBorder(toEdge edge: UIRectEdge, withColor color: UIColor = .black, inset: CGFloat = 0.0, thickness: CGFloat = 1.0) { // Remove existing borders from view and readd them for view in subviews { if view is BorderView { view.removeFromSuperview() } } if edge.contains(.all) { addSidedBorder(toEdge: .top, withColor: color, inset: inset, thickness: thickness) addSidedBorder(toEdge: .left, withColor: color, inset: inset, thickness: thickness) addSidedBorder(toEdge: .bottom, withColor: color, inset: inset, thickness: thickness) addSidedBorder(toEdge: .right, withColor: color, inset: inset, thickness: thickness) } else { if edge.contains(.top) { addSidedBorder(toEdge: .top, withColor: color, inset: inset, thickness: thickness) } if edge.contains(.left) { addSidedBorder(toEdge: .left, withColor: color, inset: inset, thickness: thickness) } if edge.contains(.bottom) { addSidedBorder(toEdge: .bottom, withColor: color, inset: inset, thickness: thickness) } if edge.contains(.right) { addSidedBorder(toEdge: .right, withColor: color, inset: inset, thickness: thickness) } } } } 

Add this code and then within a class that subclasses UIView, call:

 view.addBorder(toEdge: [.left, .right], withColor: .red, inset: 0.0, thickness: 1.0) 

Use below code in viewDidLoad

 - (void)viewDidLoad { [super viewDidLoad]; [self.view.layer setBorderWidth: 1.0]; [self.view.layer setCornerRadius:8.0f]; [self.view.layer setMasksToBounds:YES]; [self.view.layer setBorderColor:[[UIColor colorWithRed:251.0f/255.0f green:185.0f/255.0f blue:23.0f/255.0f alpha:1.0f]];` } 

this code set red color border to your view