color ios uiview border

ios - color - Agregue un borde fuera de una UIView(en lugar de adentro)



shadow view swift 4 (7)

Aumente el ancho y la altura del marco de la vista con el ancho del borde antes de agregar el borde:

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;

Si agrega un borde de una vista usando código en una vista como

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

el borde se agrega dentro de la vista como se muestra a continuación:

la vista derecha es la vista original, como puede ver, el área negra de la vista limitada es menor que la original. pero lo que quiero obtener es un borde fuera de la vista original, como este: . el área negra es igual a la original, ¿cómo puedo implementarla?


Bueno, no hay un método directo para hacerlo. Puedes considerar algunas soluciones.

  1. Cambie y aumente el marco y agregue bordercolor como lo hizo
  2. Agregue una vista detrás de la vista actual con el tamaño más grande para que aparezca como borde.Se puede trabajar como una clase de vista personalizada
  3. Si no necesita un borde definido (borde borrado), entonces puede depender de la sombra para el propósito

    [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;


Con la mejor respuesta aceptada anteriormente, hice experiencias con resultados tan poco agradables y bordes desagradables:

Por lo tanto, compartiré mi extensión UIView Swift con usted, que usa un UIBezierPath en su lugar como contorno de borde, sin bordes antiestéticos (inspirado en @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() } }

Ejemplo:

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


Lamentablemente, no hay simplemente una pequeña propiedad que puede establecer para alinear el borde con el exterior. Dibuja alineado con el interior porque las operaciones de dibujo predeterminadas de UIViews se dibujan dentro de sus límites.

La solución más simple que se me ocurre es expandir la UIView por el tamaño del ancho del borde al aplicar el borde:

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


Me gustó la solución de @picciano. Si desea un círculo explosivo en lugar de cuadrado, reemplace la función addExternalBorder con:

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 }


Ok, ya hay una respuesta aceptada, pero creo que hay una mejor manera de hacerlo, solo tienes que tener una nueva capa un poco más grande que tu vista y no enmascararla a los límites de la capa de la vista (que en realidad es el comportamiento predeterminado). Aquí está el código de ejemplo :

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;

Por supuesto, esto es si desea que su borde sea 1 unidad grande, si desea más, adapte el borderWidth y el marco de la capa en consecuencia. Esto es mejor que usar una segunda vista un poco más grande ya que un CALayer es más ligero que un UIView y no tienes que modificar el marco de myView , que es bueno, por ejemplo, si myView es un UIImageView

NB: Para mí, el resultado no era perfecto en el simulador (la capa no estaba exactamente en la posición correcta, por lo que la capa era más gruesa en un lado a veces), pero era exactamente lo que se solicita en el dispositivo real.

EDITAR

En realidad, el problema del que hablo en el NB fue simplemente porque reduje la pantalla del simulador, en tamaño normal no hay ningún problema

Espero eso ayude


Para una implementación Swift, puede agregar esto como una extensión 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() } }