Borde de UITextField solo para el lado inferior

Me gustaría mantener el borde en la parte inferior solo en UITextField . Pero no sé cómo podemos mantenerlo en el lado inferior.

¿Puedes por favor asesorarme?

Nuevo enfoque: (recomendado)

Eventualmente, encontré una forma más de hacerlo, es más simple y conveniente. Pero la única condición es que UITextField debe contener un diseño automático.

Estoy usando Visual Formatting Language (VFL) aquí, esto permitirá agregar una línea a cualquier UIControl .

Método de ayuda:

Puede agregar este método de ayuda a su clase de ayuda global (utilicé el método de clase global) o en el mismo controlador de vista (utilizando un método de instancia).

 typedef enum : NSUInteger { LINE_POSITION_TOP, LINE_POSITION_BOTTOM } LINE_POSITION; - (void) addLineToView:(UIView *)view atPosition:(LINE_POSITION)position withColor:(UIColor *)color lineWitdh:(CGFloat)width { // Add line UIView *lineView = [[UIView alloc] init]; [lineView setBackgroundColor:color]; [lineView setTranslatesAutoresizingMaskIntoConstraints:NO]; [view addSubview:lineView]; NSDictionary *metrics = @{@"width" : [NSNumber numberWithFloat:width]}; NSDictionary *views = @{@"lineView" : lineView}; [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[lineView]|" options: 0 metrics:metrics views:views]]; switch (position) { case LINE_POSITION_TOP: [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[lineView(width)]" options: 0 metrics:metrics views:views]]; break; case LINE_POSITION_BOTTOM: [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[lineView(width)]|" options: 0 metrics:metrics views:views]]; break; default: break; } } 

Uso:

 [self addLineToView:self.textField atPosition:LINE_POSITION_TOP withColor:[UIColor darkGrayColor] lineWitdh:0.5]; 

Usando Swift:

Método de ayuda:

 enum LINE_POSITION { case LINE_POSITION_TOP case LINE_POSITION_BOTTOM } func addLineToView(view : UIView, position : LINE_POSITION, color: UIColor, width: Double) { let lineView = UIView() lineView.backgroundColor = color lineView.translatesAutoresizingMaskIntoConstraints = false // This is important! view.addSubview(lineView) let metrics = ["width" : NSNumber(value: width)] let views = ["lineView" : lineView] view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[lineView]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:metrics, views:views)) switch position { case .LINE_POSITION_TOP: view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutFormatOptions(rawValue: 0), metrics:metrics, views:views)) break case .LINE_POSITION_BOTTOM: view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:metrics, views:views)) break default: break } } 

Uso:

 self.addLineToView(view: textField, position:.LINE_POSITION_BOTTOM, color: UIColor.darkGray, width: 0.5) 

Viejo enfoque:

Esta respuesta funcionará perfectamente si crea objeto UITextField programáticamente.

Nota: Si el objeto UITextField se crea en Storyboard, establezca su propiedad de Border Style UITextField en None en el Inspector de atributos del guion gráfico.

La siguiente variable textField es un objeto del control UITextField en el que se establecerá el borde inferior.

Código SWIFT:

 let border = CALayer() let width = CGFloat(2.0) border.borderColor = UIColor.darkGray.cgColor border.frame = CGRect(x: 0, y: textField.frame.size.height - width, width: textField.frame.size.width, height: textField.frame.size.height) border.borderWidth = width textField.layer.addSublayer(border) textField.layer.masksToBounds = true 

Código Objetivo C:

 CALayer *border = [CALayer layer]; CGFloat borderWidth = 2; border.borderColor = [UIColor darkGrayColor].CGColor; border.frame = CGRectMake(0, textField.frame.size.height - borderWidth, textField.frame.size.width, textField.frame.size.height); border.borderWidth = borderWidth; [textField.layer addSublayer:border]; textField.layer.masksToBounds = YES; 

Código de Xamarin:

  var border = new CALayer(); nfloat width = 2; border.BorderColor = UIColor.Black.CGColor; border.Frame = new CoreGraphics.CGRect(0, textField.Frame.Size.Height - width, textField.Frame.Size.Width, textField.Frame.Size.Height); border.BorderWidth = width; textField.Layer.AddSublayer(border); textField.Layer.MasksToBounds = true; 

Muchos usuarios tenían un problema con el diseño automático y algunas personas no podían representar el borde del UITextField. Aquí está la solución:


Si escribe el código siguiente en el método viewDidLoad() , entonces no obtendrá el marco para textField, por lo que ese borde no se procesará correctamente.

Para obtener el marco correcto para el borde, anule viewDidLayoutSubviews() y escriba el código en él.

viewDidLayoutSubviews() método viewDidLayoutSubviews() se llama después de que todas las subvistas se cargan en la vista.

No olvides que este método se llama varias veces y no forma parte del ciclo de vida de ViewController, así que ten cuidado al usarlo.

Si quieres hacerlo sin conocer marcos de antemano y sin subclases :

Swift 4.x / Swift 3.x

 extension UITextField { func setBottomBorder() { self.borderStyle = .none self.layer.backgroundColor = UIColor.white.cgColor self.layer.masksToBounds = false self.layer.shadowColor = UIColor.gray.cgColor self.layer.shadowOffset = CGSize(width: 0.0, height: 1.0) self.layer.shadowOpacity = 1.0 self.layer.shadowRadius = 0.0 } } 

Llamar como yourTextField.setBottomBorder() desde cualquier lugar sin asegurarse de que los marcos estén correctos.

El resultado se ve así:

muestra

Puede crear una subclase de UITextField como se muestra a continuación:

 class TextField : UITextField { override var tintColor: UIColor! { didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { let startingPoint = CGPoint(x: rect.minX, y: rect.maxY) let endingPoint = CGPoint(x: rect.maxX, y: rect.maxY) let path = UIBezierPath() path.move(to: startingPoint) path.addLine(to: endingPoint) path.lineWidth = 2.0 tintColor.setStroke() path.stroke() } } 
  extension UITextField { func setBottomBorder(color:String) { self.borderStyle = UITextBorderStyle.None; let border = CALayer() let width = CGFloat(1.0) border.borderColor = UIColor(hexString: color)!.CGColor border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) border.borderWidth = width self.layer.addSublayer(border) self.layer.masksToBounds = true } } 

y luego solo haz esto:

 yourTextField.setBottomBorder(color: "#3EFE46") 

Ninguna de estas soluciones cumplió realmente mis expectativas. Quería hacer una subclase de TextField ya que no quiero establecer el borde de forma manual todo el tiempo. También quería cambiar el color del borde, por ejemplo, por un error. Así que aquí está mi solución con Anchors :

 class CustomTextField: UITextField { var bottomBorder = UIView() override func awakeFromNib() { // Setup Bottom-Border self.translatesAutoresizingMaskIntoConstraints = false bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1) // Set Border-Color bottomBorder.translatesAutoresizingMaskIntoConstraints = false addSubview(bottomBorder) bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set Border-Strength } } 

—- Opcional —-

Para cambiar el color, agregue algo así a la CustomTextField Class :

 @IBInspectable var hasError: Bool = false { didSet { if (hasError) { bottomBorder.backgroundColor = UIColor.red } else { bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1) } } } 

Y para activar el Error, llámalo luego de haber creado una instancia de CustomTextField

 textField.hasError = !textField.hasError 

enter image description here

Espero que ayude a alguien;)

enter image description here

C objective

  [txt.layer setBackgroundColor: [[UIColor whiteColor] CGColor]]; [txt.layer setBorderColor: [[UIColor grayColor] CGColor]]; [txt.layer setBorderWidth: 0.0]; [txt.layer setCornerRadius:12.0f]; [txt.layer setMasksToBounds:NO]; [txt.layer setShadowRadius:2.0f]; txt.layer.shadowColor = [[UIColor blackColor] CGColor]; txt.layer.shadowOffset = CGSizeMake(1.0f, 1.0f); txt.layer.shadowOpacity = 1.0f; txt.layer.shadowRadius = 1.0f; 

Rápido

  txt.layer.backgroundColor = UIColor.white.cgColor txt.layer.borderColor = UIColor.gray.cgColor txt.layer.borderWidth = 0.0 txt.layer.cornerRadius = 5 txt.layer.masksToBounds = false txt.layer.shadowRadius = 2.0 txt.layer.shadowColor = UIColor.black.cgColor txt.layer.shadowOffset = CGSize.init(width: 1.0, height: 1.0) txt.layer.shadowOpacity = 1.0 txt.layer.shadowRadius = 1.0 

Puede crear esta extensión fuera de clase y reemplazar el ancho con el ancho de borde que desee.

Swift 4

 extension UITextField { func setBottomBorder(withColor color: UIColor) { self.borderStyle = UITextBorderStyle.none self.backgroundColor = UIColor.clear let width: CGFloat = 1.0 let borderLine = UIView(frame: CGRect(x: 0, y: self.frame.height - width, width: self.frame.width, height: width)) borderLine.backgroundColor = color self.addSubview(borderLine) } } 

Original

 extension UITextField { func setBottomBorder(borderColor: UIColor) { self.borderStyle = UITextBorderStyle.None self.backgroundColor = UIColor.clearColor() let width = 1.0 let borderLine = UIView(frame: CGRectMake(0, self.frame.height - width, self.frame.width, width)) borderLine.backgroundColor = borderColor self.addSubview(borderLine) } } 

y luego agregue esto a su viewDidLoad reemplazando suTextField con su variable UITextField y con cualquier color que desee en el borde

 yourTextField.setBottomBorder(UIColor.blackColor()) 

Esto básicamente agrega una vista con ese color en la parte inferior del campo de texto.

En Swift 3. Puede crear una extensión y agregarla después de su clase de visualización.

 extension UITextField { func setBottomBorder(borderColor: UIColor) { self.borderStyle = UITextBorderStyle.none self.backgroundColor = UIColor.clear let width = 1.0 let borderLine = UIView() borderLine.frame = CGRect(x: 0, y: Double(self.frame.height) - width, width: Double(self.frame.width), height: width) borderLine.backgroundColor = borderColor self.addSubview(borderLine) } } 

Lo que hice fue crear una extensión para UITextField y agregué una propiedad editable de Designer. Establecer esta propiedad en cualquier color cambiaría el borde (inferior) a ese color (estableciendo otros bordes en ninguno).

Como esto también requiere cambiar el color del texto del marcador de posición, también lo agregué a la extensión.

  extension UITextField { @IBInspectable var placeHolderColor: UIColor? { get { return self.placeHolderColor } set { self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSForegroundColorAttributeName: newValue!]) } } @IBInspectable var bottomBorderColor: UIColor? { get { return self.bottomBorderColor } set { self.borderStyle = UITextBorderStyle.None; let border = CALayer() let width = CGFloat(0.5) border.borderColor = newValue?.CGColor border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) border.borderWidth = width self.layer.addSublayer(border) self.layer.masksToBounds = true } } } 

Aquí está el código swift3 con @IBInspectable

crear un nuevo archivo Cocoa Touch Class Swift File

 import UIKit extension UIView { @IBInspectable var cornerRadius: CGFloat { get { return layer.cornerRadius } set { layer.cornerRadius = newValue layer.masksToBounds = newValue > 0 } } @IBInspectable var borderWidth: CGFloat { get { return layer.borderWidth } set { layer.borderWidth = newValue } } @IBInspectable var borderColor: UIColor? { get { return UIColor(cgColor: layer.borderColor!) } set { layer.borderColor = newValue?.cgColor } } @IBInspectable var leftBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: 0.0, y: 0.0, width: newValue, height: bounds.height)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = UIColor(cgColor: layer.borderColor!) line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line(==lineWidth)]", options: [], metrics: metrics, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line]|", options: [], metrics: nil, views: views)) } } @IBInspectable var topBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: 0.0, y: 0.0, width: bounds.width, height: newValue)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = borderColor line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line]|", options: [], metrics: nil, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line(==lineWidth)]", options: [], metrics: metrics, views: views)) } } @IBInspectable var rightBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: bounds.width, y: 0.0, width: newValue, height: bounds.height)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = borderColor line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "[line(==lineWidth)]|", options: [], metrics: metrics, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line]|", options: [], metrics: nil, views: views)) } } @IBInspectable var bottomBorderWidth: CGFloat { get { return 0.0 // Just to satisfy property } set { let line = UIView(frame: CGRect(x: 0.0, y: bounds.height, width: bounds.width, height: newValue)) line.translatesAutoresizingMaskIntoConstraints = false line.backgroundColor = borderColor line.tag = 110 self.addSubview(line) let views = ["line": line] let metrics = ["lineWidth": newValue] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line]|", options: [], metrics: nil, views: views)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[line(==lineWidth)]|", options: [], metrics: metrics, views: views)) } } func removeborder() { for view in self.subviews { if view.tag == 110 { view.removeFromSuperview() } } } 

}

y reemplace el archivo con el siguiente código y obtendrá la opción en el inspector de atributos del guión gráfico como este

enter image description here

Disfruta 🙂

Por favor, eche un vistazo a la muestra del código a continuación;

Swift 4:

 @IBDesignable class DesignableUITextField: UITextField { let border = CALayer() @IBInspectable var borderColor: UIColor? { didSet { setup() } } @IBInspectable var borderWidth: CGFloat = 0.5 { didSet { setup() } } func setup() { border.borderColor = self.borderColor?.cgColor border.borderWidth = borderWidth self.layer.addSublayer(border) self.layer.masksToBounds = true } override func layoutSubviews() { super.layoutSubviews() border.frame = CGRect(x: 0, y: self.frame.size.height - borderWidth, width: self.frame.size.width, height: self.frame.size.height) } } 

** Aquí myTF es una salida para MT TEXT FIELD **

  let border = CALayer() let width = CGFloat(2.0) border.borderColor = UIColor.darkGray.cgColor border.frame = CGRect(x: 0, y: self.myTF.frame.size.height - width, width: self.myTF.frame.size.width, height: self.myTF.frame.size.height) border.borderWidth = width self.myTF.layer.addSublayer(border) self.myTF.layer.masksToBounds = true 

puede crear una imagen para el borde inferior y establecerla en el fondo de su UITextField:

  yourTextField.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"yourBorderedImageName"]]; 

¡o establezca borderStyle en none y ponga la imagen de la línea exactamente igual a la longitud del campo de texto!

Puede usar esto ORGANIZADO y también puede PERSONALIZAR esta extensión más:

Implementación de una línea ” en viewDidAppear (para que el tamaño del fotogtwig sea correcto):

 // Add layer in your textfield yourTextField.addLayer(.bottom).addPadding(.left) // Extension extension UITextField { enum Position { case up, bottom, right, left } // MARK: - Add Single Line Layer func addLayer(_ position: Position) -> UITextField { // bottom layer let bottomLayer = CALayer() // set width let height = CGFloat(1.0) bottomLayer.borderWidth = height // set color bottomLayer.borderColor = UIColor.white.cgColor // set frame // y position changes according to the position let yOrigin = position == .up ? 0.0 : frame.size.height - height bottomLayer.frame = CGRect.init(x: 0, y: yOrigin, width: frame.size.width, height: height) layer.addSublayer(bottomLayer) layer.masksToBounds = true return self } // Add right/left padding view in textfield func addPadding(_ position: Position, withImage image: UIImage? = nil) { let paddingHeight = frame.size.height let paddingViewFrame = CGRect.init(x: 0.0, y: 0.0, width: paddingHeight * 0.6, height: paddingHeight) let paddingImageView = UIImageView.init(frame: paddingViewFrame) paddingImageView.contentMode = .scaleAspectFit if let paddingImage = image { paddingImageView.image = paddingImage } // Add Left/Right view mode switch position { case .left: leftView = paddingImageView leftViewMode = .always case .right: rightView = paddingImageView rightViewMode = .always default: break } } } 
 import UIkit extension UITextField { func underlinedLogin() { let border = CALayer() let width = CGFloat(1.0) border.borderColor = UIColor.black.cgColor border.frame = CGRect(x: 0, y: self.frame.size.height - width, width: self.frame.size.width, height: self.frame.size.height) border.borderWidth = width self.layer.addSublayer(border) self.layer.masksToBounds = true } 

}

método de llamada en viewdidload

mobileNumberTextField.underlinedLogin()

passwordTextField.underlinedLogin()

// seleccionar como campo de texto en mainstoryboard

imagen