Agregue la línea de fondo para ver en SwiftUI / Swift / Objective-C / Xamarin

155

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

¿Me puede aconsejar por favor?

dhaval shah
fuente

Respuestas:

314

Estoy creando un textFieldcomponente personalizado para que sea un componente reutilizable para SwiftUI

SwiftUI

struct CustomTextField: View {
    var placeHolder: String
    @Binding var value: String

    var lineColor: Color
    var width: CGFloat

    var body: some View {
        VStack {
            TextField(self.placeHolder, text: $value)
            .padding()
            .font(.title)

            Rectangle().frame(height: self.width)
                .padding(.horizontal, 20).foregroundColor(self.lineColor)
        }
    }
}

Uso:

@Binding var userName: String
@Binding var password: String

var body: some View {
    VStack(alignment: .center) {
        CustomTextField(placeHolder: "Username", value: $userName, lineColor: .white, width: 2)
        CustomTextField(placeHolder: "Password", value: $password, lineColor: .white, width: 2)
    }
}


Swift 5.0

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

Puedes crear una UIViewclase de extensión comoUIView+Extention.swift

import UIKit

enum LINE_POSITION {
    case LINE_POSITION_TOP
    case LINE_POSITION_BOTTOM
}

extension UIView {
    func addLine(position : LINE_POSITION, color: UIColor, width: Double) {
        let lineView = UIView()
        lineView.backgroundColor = color
        lineView.translatesAutoresizingMaskIntoConstraints = false // This is important!
        self.addSubview(lineView)

        let metrics = ["width" : NSNumber(value: width)]
        let views = ["lineView" : lineView]
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[lineView]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))

        switch position {
        case .LINE_POSITION_TOP:
            self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
            break
        case .LINE_POSITION_BOTTOM:
            self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
            break
        }
    }
}

Uso:

textField.addLine(position: .LINE_POSITION_BOTTOM, color: .darkGray, width: 0.5)

C objetivo:

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

typedef enum : NSUInteger {
    LINE_POSITION_TOP,
    LINE_POSITION_BOTTOM
} LINE_POSITION;


- (void) addLine:(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 addLine:self.textField atPosition:LINE_POSITION_TOP withColor:[UIColor darkGrayColor] lineWitdh:0.5];

Código 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;
Kampai
fuente
156

Si desea hacerlo sin conocer los cuadros de antemano, sin subclases y sin Autolayout :

Swift 5 / 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
  }
}

Llame yourTextField.setBottomBorder()desde cualquier lugar sin asegurarse de que los marcos sean correctos.

El resultado se ve así:

muestra

IU rápida

struct MyTextField: View {
  var myPlaceHolder: String
  @Binding var text: String

  var underColor: Color
  var height: CGFloat

  var body: some View {
    VStack {
        TextField(self.myPlaceHolder, text: $text)
        .padding()
        .font(.title)

        Rectangle().frame(height: self.height)
            .padding(.horizontal, 24).foregroundColor(self.underColor)
    }
  }
}
Sasquatch
fuente
1
A mí me funciona, se puede mostrar algo de su código, por lo que podemos mirar en
sasquatch
1
Probar viewDidLoad()?
sasquatch
1
@markhorrocks ¿Puedes compartir tu resultado? Lo probé y funcionó para mí.
sasquatch
11
Si cambiamos el color de fondo a color claro, no funciona.
Sábado
8
si. Si cambiamos el color blanco a color claro en self.layer.backgroundColor = UIColor.white.cgColor no funciona
Satyam
44

Puede crear una subclase de UITextFieldcomo 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()
    }
}
usuario1046037
fuente
El mejor enfoque para hacer. Solo quería saber cómo cambiar el color de subrayado durante la edición o durante el método "didBeginEditing" y cambiar el color en "didEndEditing"
Deepak Chaudhary
Ver la respuesta actualizada, establecer el tintColoren didBeginEditingedidEndEditing
user1046037
Esta es la solución que usé. Reste 4 de maxY para mover el subrayado más cerca de la entrada de texto.
markhorrocks 05 de
24

Ninguna de estas soluciones realmente cumplió con mis expectativas. Quería subclasificar el TextField ya que no quiero establecer el borde manualmente 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 como esto a 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, llame a esto después de crear una instancia de CustomTextField

textField.hasError = !textField.hasError

ingrese la descripción de la imagen aquí

Espero que ayude a alguien;)

inf1783
fuente
2
La mejor solución hasta ahora, incluso puede modificarla para otros estados de "validación"
Bruno Ferreira
22
 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")
idris yıldız
fuente
3
Estaba pensando en hacer esto, pero si usamos esto viewDidLoad(), el marco sería incorrecto. Entonces tenemos 2 opciones: viewDidLayoutSubviews()o viewDidAppear(). Pero viewDidLayoutSubviews()llamar varias veces y llamar desde viewDidAppear()no sería una buena experiencia.
iAkshay
viewDidLayoutSubviews()tampoco funcionará si el campo de texto está anidado dentro multiple View. Obtendrás múltiples broder.
Kunal Kumar
13

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 yourTextField con su variable UITextField y con cualquier color que desee en el borde

yourTextField.setBottomBorder(UIColor.blackColor())

Básicamente, esto agrega una vista con ese color en la parte inferior del campo de texto.

Rishabh Wadhwa
fuente
Gran solución, funciona con un fondo claro a diferencia de algunos de los otros.
Serdnad
1
recuerde agregar una llamada func a viewDidLayoutSubviews () si usa el diseño automático :) de lo contrario, su línea no coincidirá correctamente con el marco.
GordonW
10

ingrese la descripción de la imagen aquí

C objetivo

        [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
Mitul Marsoniya
fuente
7

Lo que hice fue crear una extensión para UITextField y agregué una propiedad editable del Diseñador. Establecer esta propiedad en cualquier color cambiaría el borde (inferior) a ese color (establecer 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

        }
    }
}
Krishna Vedula
fuente
Creo que en Swift 4.0 necesita cambiar el "conjunto" a "didSet", pero de lo contrario funciona, gracias
C0D3
6

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

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)
    }
}
afrodev
fuente
1
Esto solo funcionó para mí si lo llama en viewDidLayoutSubviews () y no en viewDidLoad (). ¿Era esa la intención aquí?
cheznead
6

Por favor, eche un vistazo a la muestra de 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)
    }
 }
iman
fuente
4

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

ingrese la descripción de la imagen aquí

Disfruta :)

Azharhussain Shaikh
fuente
1

** Aquí myTF es 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
Sai kumar Reddy
fuente
0

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 coloque la imagen de la línea exactamente igual a la longitud del campo de texto!

Saurabh Prajapati
fuente
Echaré un vistazo a este saurabh. Pero será genial que podamos hacerlo por código. ¿Tienes alguna idea?
dhaval shah
0

Código actualizado:

Swift 5.0

extension UITextField {
  func addUnderline() { 
   let layer = CALayer()
   layer.backgroundColor = #colorLiteral(red: 0.6666666865, green: 0.6666666865, blue: 0.6666666865, alpha: 1)
   layer.frame = CGRect(x: 0.0, y: self.frame.size.height - 1.0, width: self.frame.size.width, height: 1.0)
   self.clipsToBounds = true
   self.layer.addSublayer(layer)
   self.setNeedsDisplay()} }

Ahora llame a este func en viewDidLayoutSubviews ()

override func viewDidLayoutSubviews() {
    textField.addUnderline()
}

NOTA: Este método solo funcionará en viewDidLayoutSubviews ()

Prakhar Prakash Bhardwaj
fuente
0

He analizado cada una de estas soluciones que también parecen funcionar con un problema. Modo oscuro y la configuración de fondo

La configuración de fondo del UITextField debe coincidir con el fondo de la vista principal o no aparece ninguna línea

Entonces, esto funcionará en modo claro. Para trabajar en modo oscuro, cambie el color de fondo a negro y funciona. Excluya el color de fondo y la línea no aparece.

let field = UITextField() 
field.backgroundColor = UIColor.white
field.bottomBorderColor = UIColor.red

Esto terminó siendo la mejor solución para mí.

extension UITextField {

    func addPadding() {
        let paddingView = UIView(frame: CGRect(x:0, y:0, width: 10, height: self.frame.height))
        self.leftView = paddingView
        self.leftViewMode = .always
      }

      @IBInspectable var placeHolderColor: UIColor? {
          get {
              return self.placeHolderColor
          }
          set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: newValue!])
          }
      }

      @IBInspectable var bottomBorderColor: UIColor? {
          get {
              return self.bottomBorderColor
          }
          set {
            self.borderStyle = .none
            self.layer.masksToBounds = false
            self.layer.shadowColor = newValue?.cgColor
            self.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
            self.layer.shadowOpacity = 1.0
            self.layer.shadowRadius = 0.0
          }
      }
    }
Taylor Maxwell
fuente
0
let border = CALayer()
     let lineWidth = CGFloat(0.3)
     border.borderColor = UIColor.lightGray.cgColor
     border.frame = CGRect(x: 0, y: emailTextField.frame.size.height - lineWidth, width:  emailTextField.frame.size.width, height: emailTextField.frame.size.height)
     border.borderWidth = lineWidth
     emailTextField.layer.addSublayer(border)
     emailTextField.layer.masksToBounds = true

Tutorial

Abhi Kapoor
fuente
Trabaja para mí en Swift 4.2
Abhi Kapoor
0

SwiftUI

en SwiftUI, hay una Viewllamada Dividerque se adapta perfectamente a esto. Puede agregarlo debajo de cualquier vista incrustándolos en un simple VStack:

VStack {
    Text("This could be any View")
    Divider()
}
Mojtaba Hosseini
fuente
-1

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

" Implementación de una línea " en viewDidAppear (para que el tamaño del marco 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
        }
    }
}
Bhuvan Bhatt
fuente
-1
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()

// selecciona como campo de texto en mainstoryboard

imagen

Rupesh Babu
fuente
-1

Para ver: (más recomendado)

Funciona para todo tipo de UIViewsubclase (vista, archivo de texto, etiqueta, etc.) usandoUIView extension

Es más simple y conveniente. Pero la única condición es que viewdebe contener un diseño automático.

extension UIView {
    enum Line_Position {
        case top
        case bottom
    }

    func addLine(position : Line_Position, color: UIColor, height: Double) {
        let lineView = UIView()
        lineView.backgroundColor = color
        lineView.translatesAutoresizingMaskIntoConstraints = false // This is important!
        self.addSubview(lineView)

        let metrics = ["width" : NSNumber(value: height)]
        let views = ["lineView" : lineView]
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[lineView]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))

        switch position {
        case .top:
            self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[lineView(width)]", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
            break
        case .bottom:
            self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[lineView(width)]|", options:NSLayoutConstraint.FormatOptions(rawValue: 0), metrics:metrics, views:views))
            break
        }
    }
}

¿Cómo utilizar?

// UILabel
self.lblDescription.addLine(position: .bottom, color: UIColor.blue, height: 1.0)

ingrese la descripción de la imagen aquí
y

// UITextField
self.txtArea.addLine(position: .bottom, color: UIColor.red, height: 1.0)

ingrese la descripción de la imagen aquí

Ilesh P
fuente
¿Hay una manera fácil de eliminar esta línea después de configurarla? Por ejemplo, quiero tenerlo mientras mi textField está activo; de lo contrario, volvería al estilo predeterminado.
timetraveler90
sí, simplemente sostenga el objeto cualquier eliminar u ocultar / mostrar cuando lo necesite. :)
Ilesh P