Ajouter la ligne du bas à afficher dans SwiftUI / Swift / Objective-C / Xamarin

155

Je voudrais garder la bordure dans la partie inférieure uniquement UITextField. Mais je ne sais pas comment on peut garder ça en bas.

Pouvez-vous me conseiller?

dhaval shah
la source

Réponses:

314

Je crée un textFieldcomposant personnalisé pour en faire un composant réutilisable pour 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)
        }
    }
}

Usage:

@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

J'utilise le langage de formatage visuel (VFL) ici, cela permettra d'ajouter une ligne à tout UIControl.

Vous pouvez créer une UIViewclasse d'extension commeUIView+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
        }
    }
}

Usage:

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

Objectif c:

Vous pouvez ajouter cette méthode d'assistance à votre classe d'assistance globale (j'ai utilisé la méthode de classe globale) ou dans le même contrôleur de vue (à l'aide d'une méthode d'instance).

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

Usage:

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

Code 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
la source
156

Si vous voulez faire sans connaître les cadres à l' avance, sans sous - classement et sans 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
  }
}

Appelez comme yourTextField.setBottomBorder()de n'importe où sans vous assurer que les cadres sont corrects.

Le résultat ressemble à ceci:

échantillon

Interface utilisateur rapide

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
la source
1
Cela fonctionne pour moi, pouvez-vous montrer une partie de votre code, afin que nous puissions examiner
sasquatch
1
Essayer viewDidLoad()?
sasquatch du
1
@markhorrocks Pouvez-vous partager votre résultat? Je l'ai essayé et cela a fonctionné pour moi.
sasquatch
11
Si nous changeons la couleur d'arrière-plan en couleur claire, cela ne fonctionne pas.
Satyam
8
Oui. Si nous changeons la couleur blanche en couleur claire dans self.layer.backgroundColor = UIColor.white.cgColor cela ne fonctionne pas
Satyam
44

Vous pouvez créer une sous-classe de UITextFieldcomme indiqué ci-dessous:

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()
    }
}
utilisateur1046037
la source
Meilleure approche à faire. Je voulais juste savoir comment changer la couleur de soulignement pendant l'édition ou pendant la méthode "didBeginEditing" et changer la couleur sur "didEndEditing"
Deepak Chaudhary
Voir la réponse mise à jour, définir les paramètres tintColorin didBeginEditingetdidEndEditing
user1046037
C'est la solution que j'ai utilisée. J'ai soustrait 4 de maxY pour rapprocher le soulignement de l'entrée de texte.
markhorrocks
24

Aucune de ces solutions n'a vraiment répondu à mes attentes. Je voulais sous -classer le TextField car je ne veux pas définir la bordure manuellement tout le temps. Je voulais aussi changer la couleur de la bordure par exemple pour une erreur. Voici donc ma solution avec 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

    }
}

---- Optionnel ----

Pour changer la couleur, ajoutez qc comme ceci au CustomTextField Class:

@IBInspectable var hasError: Bool = false {
    didSet {

        if (hasError) {

            bottomBorder.backgroundColor = UIColor.red

        } else {

            bottomBorder.backgroundColor = UIColor(rgb: 0xE2DCD1)

        }

    }
}

Et pour déclencher l'erreur, appelez ceci après avoir créé une instance de CustomTextField

textField.hasError = !textField.hasError

entrez la description de l'image ici

J'espère que ça aide quelqu'un;)

inf1783
la source
2
Meilleure solution jusqu'à présent, vous pouvez même la modifier pour d'autres états de «validation»
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
   }
}

puis faites ceci:

yourTextField.setBottomBorder(color: "#3EFE46")
idris yıldız
la source
3
Je pensais faire comme ça, mais si nous l'utilisons dans viewDidLoad(), le cadre serait incorrect. Nous avons donc 2 choix: viewDidLayoutSubviews()ou viewDidAppear(). Mais viewDidLayoutSubviews()appeler plusieurs fois et appeler de viewDidAppear()ne serait pas une bonne expérience.
iAkshay
viewDidLayoutSubviews()ne fonctionnera pas non plus si le champ de texte est imbriqué à l'intérieur multiple View. Vous obtiendrez plusieurs brodeurs.
Kunal Kumar
13

Vous pouvez créer cette extension en dehors de la classe et remplacer width par le borderWidth de votre choix.

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

puis ajoutez ceci à votre viewDidLoad en remplaçant yourTextField par votre variable UITextField et par la couleur de votre choix dans la bordure

yourTextField.setBottomBorder(UIColor.blackColor())

Cela ajoute essentiellement une vue avec cette couleur au bas du champ de texte.

Rishabh Wadhwa
la source
Excellente solution, fonctionne avec un fond clair contrairement à certains des autres.
Serdnad
1
n'oubliez pas d'ajouter un appel func à viewDidLayoutSubviews () si vous utilisez la mise en page automatique :) sinon votre ligne ne correspondra pas correctement à frame.
GordonW
10

entrez la description de l'image ici

Objectif c

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

Rapide

        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
la source
7

Ce que j'ai fait, c'est de créer une extension pour UITextField et d'ajouter une propriété modifiable Designer. Définir cette propriété sur n'importe quelle couleur changerait la bordure (en bas) en cette couleur (définir les autres bordures sur aucune).

Étant donné que cela nécessite également de changer la couleur du texte de l'espace réservé, j'ai également ajouté cela à l'extension.

    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
la source
Je pense que dans Swift 4.0, vous devez changer le "set" en "didSet" mais sinon cela fonctionne, merci
C0D3
6

Sur Swift 3. Vous pouvez créer une extension et l'ajouter après votre classe d'affichage.

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
la source
1
Cela n'a fonctionné pour moi que si vous l'appelez dans viewDidLayoutSubviews () et non viewDidLoad (). Était-ce l'intention ici?
cheznead
6

Veuillez consulter l'exemple de code ci-dessous;

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
la source
4

Voici le code swift3 avec @IBInspectable

créer un nouveau fichier 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()
           }

      }
 }

}

et remplacez le fichier par le code ci-dessous et vous obtiendrez l'option dans l'inspecteur d'attributs de storyboard comme celui-ci

entrez la description de l'image ici

Prendre plaisir :)

Azharhussain Shaikh
la source
1

** Ici myTF est la sortie pour 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
la source
0

vous pouvez créer une image pour la bordure inférieure et la définir sur l'arrière-plan de votre UITextField:

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

ou définissez borderStyle sur none et mettez l'image de la ligne exactement égale à textfield!

Saurabh Prajapati
la source
Je vais jeter un oeil à celui-ci saurabh. Mais ce sera génial de pouvoir le faire par code? Avez-vous une idée?
dhaval shah
0

Code mis à jour:

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

Appelez maintenant cette fonction dans viewDidLayoutSubviews ()

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

REMARQUE: cette méthode ne fonctionnera que dans viewDidLayoutSubviews ()

Prakhar Prakash Bhardwaj
la source
0

J'ai examiné chacune de ces solutions qui semblent également fonctionner avec un problème. Mode sombre et réglage de l'arrière-plan

Le paramètre d'arrière-plan de UITextField doit correspondre à l'arrière-plan de la vue parente ou aucune ligne n'apparaît

Donc, cela fonctionnera en mode clair Pour arriver au travail en mode sombre, changez la couleur d'arrière-plan en noir et cela fonctionne.Excluez la couleur arrière et la ligne n'apparaît pas

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

Cela a fini par être la meilleure solution pour moi

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
la source
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

Didacticiel

Abhi Kapoor
la source
Travaillez pour moi dans Swift 4.2
Abhi Kapoor
0

SwiftUI

dans SwiftUI, il y a un Viewappelé Dividerqui correspond parfaitement à cela. Vous pouvez l'ajouter sous n'importe quelle vue en les intégrant dans un simple VStack:

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

Vous pouvez utiliser cette ORGANISÉ et peut également PERSONNALISER cette nouvelle extension:

" One Line Implementation " dans viewDidAppear (pour que la taille du cadre soit correcte):

// 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
la source
-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
}

}

call méthode sur viewdidload

mobileNumberTextField.underlinedLogin()

passwordTextField.underlinedLogin()

// sélectionner comme champ de texte sur le tableau principal

image

Rupesh Babu
la source
-1

Pour la vue: (le plus recommandé)

Cela fonctionne pour tous les types de UIViewsous - classes (vue, fichier texte, étiquette, etc.) en utilisantUIView extension

C'est plus simple et plus pratique. Mais la seule condition est que le viewdoit contenir une mise en page automatique.

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
        }
    }
}

Comment utiliser?

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

entrez la description de l'image ici
et

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

entrez la description de l'image ici

Ilesh P
la source
Existe-t-il un moyen simple de supprimer cette ligne après l'avoir définie? Par exemple, je veux l'avoir pendant que mon textField est actif sinon je le retournerais au style par défaut.
timeraveler90
oui, maintenez simplement un objet à supprimer ou à masquer / afficher lorsque vous en avez besoin. :)
Ilesh P