Swift agregar icono / imagen en UITextField

101

Me gustaría agregar un icono / imagen en UITextField. El icono / imagen debe dejarse como marcador de posición.

ingrese la descripción de la imagen aquí

Probé esto:

var imageView = UIImageView();
var image = UIImage(named: "email.png");
imageView.image = image;
emailField.leftView = imageView;

Gracias.

informatiker
fuente
74
Agregó puntos y coma por accidente: D
Gerald
10
emailField.leftView = UIImageView(image: UIImage(named: "search")):)
tspentzas
Usando @IBDesignablepodemos hacer esto de una manera elegante como en este ejemplo: stackoverflow.com/a/51841433/8238512
Rizwan

Respuestas:

120

Intenta agregar emailField.leftViewMode = UITextFieldViewMode.Always

(El valor predeterminado leftViewModees Never)

Respuesta actualizada para Swift 4

emailField.leftViewMode = UITextFieldViewMode.always

emailField.leftViewMode = .always
Markus
fuente
Hmm funcionó para mí, ¿lo probaste con el valor actualizado ( UITextFieldViewMode.Always)? ¿Tienes idea de qué fue lo que no funcionó? (por ejemplo, ¿se compiló?)
Markus
Este es mi código completo en la sección 'ViewWillAppear': 'var imageView = UIImageView (); var image = UIImage (llamado: "email.png"); imageView.image = imagen; emailTextField.leftView = imageView; emailTextField.leftViewMode = UITextFieldViewMode.Always
informatiker
@informatiker Ok, ¿estás seguro de que tienes las conexiones correctas? Si, ​​por ejemplo, estableces el color de fondo del, emailTextField¿realmente cambia? ¿Y estás seguro de que la imagen está ahí? Por ejemplo, cree otro UIImageView y cárguelo imageen ese para verificar que funciona.
Markus
4
si gracias. El problema era que el icono era blanco y no se veía sobre un fondo blanco.
informatiker
5
Continué mi búsqueda y finalmente lo puse a funcionar, me perdí de configurar el marco para la vista de imagen. Parece que necesitamos establecer un marco en la imagen antes de agregarlo al campo uitextfield. Algo como estoimageView1.frame = CGRect(x: 5, y: 0, width: userName.frame.height, height: userName.frame.height) view.addSubview(imageView1)
Sashi
123

Sahil tiene una gran respuesta y quería tomar eso y expandirlo en un @IBDesignable para que los desarrolladores puedan agregar imágenes a sus UITextFields en el Storyboard.

Rápido 4.2

import UIKit

@IBDesignable
class DesignableUITextField: UITextField {
    
    // Provides left padding for images
    override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
        var textRect = super.leftViewRect(forBounds: bounds)
        textRect.origin.x += leftPadding
        return textRect
    }
    
    @IBInspectable var leftImage: UIImage? {
        didSet {
            updateView()
        }
    }
    
    @IBInspectable var leftPadding: CGFloat = 0
    
    @IBInspectable var color: UIColor = UIColor.lightGray {
        didSet {
            updateView()
        }
    }
    
    func updateView() {
        if let image = leftImage {
            leftViewMode = UITextField.ViewMode.always
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
            imageView.contentMode = .scaleAspectFit
            imageView.image = image
            // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
            imageView.tintColor = color
            leftView = imageView
        } else {
            leftViewMode = UITextField.ViewMode.never
            leftView = nil
        }
        
        // Placeholder text color
        attributedPlaceholder = NSAttributedString(string: placeholder != nil ?  placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: color])
    }
}

¿Que está sucediendo aquí?

Este designable le permite:

  • Establecer una imagen a la izquierda
  • Agregue relleno entre el borde izquierdo de UITextField y la imagen
  • Establezca un color para que la imagen y el texto del marcador de posición coincidan

Notas

  • Para que cambie el color de la imagen, debe seguir esa nota en el comentario en el código
  • El color de la imagen no cambiará en el Storyboard. Tienes que ejecutar el proyecto para ver el color en el Simulador / dispositivo.

Designable en el Storyboard Storyboard

En tiempo de ejecución Tiempo de ejecución

Mark Moeykens
fuente
5
Agregado en imageView.contentMode = .AspectFit, para evitar el cambio de tamaño de la imagen.
Jerland2
3
¡Muchas gracias por la gran publicación! Lo modifiqué para que también tenga una opción RTL. Código disponible aquí: pastebin.com/7CCm6NEB
Ali Almohsen
¡Buen trabajo, chicos! Yo también terminé haciendo lo mismo más tarde. Ja, ja
Mark Moeykens
14
¿Qué pasa con el relleno entre la imagen y el texto?
Zaporozhchenko Oleksandr
1
la Gran respuesta.
Ripa Saha
51

Solo quiero agregar algo más aquí:

Si desea agregar la imagen en UITextFieldel lado izquierdo, use la leftViewpropiedad deUITextField

NOTA: No olvide establecer leftViewModeen UITextFieldViewMode.Alwaysy para el derecho rightViewModeal UITextFieldViewMode.Always andvalor predeterminadoUITextFieldViewModeNever

por ejemplo

Para agregar una imagen en el lado izquierdo

textField.leftViewMode = UITextFieldViewMode.Always
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
let image = UIImage(named: imageName)
imageView.image = image
textField.leftView = imageView

Para agregar una imagen en el lado derecho

textField.rightViewMode = UITextFieldViewMode.Always
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
let image = UIImage(named: imageName)
imageView.image = image
textField.rightView = imageView

NOTA: algunas cosas que debe tener en cuenta al agregar una imagen UITextFielden el lado izquierdo o derecho.

  • No olvides dar un marco del ImageViewque vas a agregarUITextField

    let imageView = UIImageView (marco: CGRect (x: 0, y: 0, ancho: 20, alto: 20))

  • si el fondo de la imagen es blanco, la imagen no se verá en UITextField

  • si desea agregar una imagen a la posición específica, debe agregarla ImageViewcomo subvista de UITextField.

Actualización para Swift 3.0

@Mark Moeykens lo gastó maravillosamente y lo hizo @IBDesignable .

Modifiqué y agregué algunas características más (agregue Bottom Line y relleno para la imagen derecha) en esto.

NOTA si desea agregar una imagen en el lado derecho, puede seleccionar la Force Right-to-Leftopción en el semanticgenerador de interfaces (pero para el relleno de la imagen derecha no funcionará hasta que anule el método rightViewRect).

ingrese la descripción de la imagen aquí

He modificado esto y puedo descargar la fuente desde aquí ImageTextField

ingrese la descripción de la imagen aquí

Sahil
fuente
¿Cómo puedo agregar esto en extensiones y llamar a mi viewcontroller? me pueden sugerir
narahari_arjun
¡Muy simple! simplemente cree la función en la extensión UIViewController y pase imagename y textfield ref cuando llame a esa función.
Sahil
extension UIViewController {func addLeftImage (imageName: String, textField: UITextField) {textField.leftViewMode = UITextFieldViewMode.Always let imageView = UIImageView (frame: CGRect (x: 0, y: 0, width: 20, height: 20)) let image = UIImage (named: imageName) imageView.image = image textField.leftView = imageView}} y llámelo como self.addLeftImage ("imganame", textField: yourtextfield)
Sahil
Traté de cambiar la posición del icono. pero no cambiado con este código
Rahul Phate
22

UITextField con imagen (izquierda o derecha)

Otra forma, inspirada en publicaciones anteriores para hacer una extensión.

Podemos poner la imagen a la derecha oa la izquierda

extension UITextField {

enum Direction {
    case Left
    case Right
}

// add image to textfield
func withImage(direction: Direction, image: UIImage, colorSeparator: UIColor, colorBorder: UIColor){
    let mainView = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 45))
    mainView.layer.cornerRadius = 5

    let view = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 45))
    view.backgroundColor = .white
    view.clipsToBounds = true
    view.layer.cornerRadius = 5
    view.layer.borderWidth = CGFloat(0.5)
    view.layer.borderColor = colorBorder.cgColor
    mainView.addSubview(view)

    let imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFit
    imageView.frame = CGRect(x: 12.0, y: 10.0, width: 24.0, height: 24.0)
    view.addSubview(imageView)

    let seperatorView = UIView()
    seperatorView.backgroundColor = colorSeparator
    mainView.addSubview(seperatorView)

    if(Direction.Left == direction){ // image left
        seperatorView.frame = CGRect(x: 45, y: 0, width: 5, height: 45)
        self.leftViewMode = .always
        self.leftView = mainView
    } else { // image right
        seperatorView.frame = CGRect(x: 0, y: 0, width: 5, height: 45)
        self.rightViewMode = .always
        self.rightView = mainView
    }

    self.layer.borderColor = colorBorder.cgColor
    self.layer.borderWidth = CGFloat(0.5)
    self.layer.cornerRadius = 5
}

}

Utilizar :

if let myImage = UIImage(named: "my_image"){
    textfield.withImage(direction: .Left, image: myImage, colorSeparator: UIColor.orange, colorBorder: UIColor.black)
}

Disfruta :)

Insou
fuente
1
Me alegraste el día, personalicé "view.backgroundColor" y "imageView.tintColor" para que sea completamente personalizable. Muchas gracias por tu respuesta xD
Andres Paladines
1
Esto es increíble
Mohamed Haseel
1
Estas son las mejores y simples respuestas
Gerardo Salazar Sánchez
14

Para crear relleno, me gusta colocar la imagen dentro de una vista de contenedor. Puede eliminar el color de fondo una vez que esté satisfecho con la ubicación del icono.

ingrese la descripción de la imagen aquí

let imageView = UIImageView(frame: CGRect(x: 8.0, y: 8.0, width: 24.0, height: 24.0))
let image = UIImage(named: "my_icon")
imageView.image = image
imageView.contentMode = .scaleAspectFit
imageView.backgroundColor = UIColor.red

let view = UIView(frame: CGRect(x: 0, y: 0, width: 32, height: 40))
view.addSubview(imageView)
view.backgroundColor = .green
textField.leftViewMode = UITextFieldViewMode.always
textField.leftView = view
S Yoshida
fuente
Gracias. Buena explicación con colores.
Hamid Reza Ansari
13

para Swift 3.0 agregue una imagen en el lado izquierdo del campo de texto

textField.leftView = UIImageView(image: "small-calendar")
textField.leftView?.frame = CGRect(x: 0, y: 5, width: 20 , height:20)
textField.leftViewMode = .always
Maulik Patel
fuente
6

Rápido 5

@IBOutlet weak var paswd: UITextField! {
    didSet{
      paswd.setLeftView(image: UIImage.init(named: "password")!)
      paswd.tintColor = .darkGray
      paswd.isSecureTextEntry = true
    }   
 }

He creado la extensión

extension UITextField {
  func setLeftView(image: UIImage) {
    let iconView = UIImageView(frame: CGRect(x: 10, y: 10, width: 25, height: 25)) // set your Own size
    iconView.image = image
    let iconContainerView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 45))
    iconContainerView.addSubview(iconView)
    leftView = iconContainerView
    leftViewMode = .always
    self.tintColor = .lightGray
  }
}

Resultado

ingrese la descripción de la imagen aquí

Gurjinder Singh
fuente
3

Creé un IBDesignable simple. Úsalo como quieras. Simplemente haga que su UITextField confirme a esta clase.

import UIKit

@IBDesignable
class RoundTextField : UITextField {
    @IBInspectable var cornerRadius : CGFloat = 0{
        didSet{
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }

    @IBInspectable var borderWidth : CGFloat = 0 {
        didSet{
            layer.borderWidth = borderWidth
        }
    }

    @IBInspectable var borderColor : UIColor? {
        didSet {
            layer.borderColor = borderColor?.cgColor
        }
    }

    @IBInspectable var bgColor : UIColor? {
        didSet {
            backgroundColor = bgColor
        }
    }

    @IBInspectable var leftImage : UIImage? {
        didSet {
            if let image = leftImage{
                leftViewMode = .always
                let imageView = UIImageView(frame: CGRect(x: 20, y: 0, width: 20, height: 20))
                imageView.image = image
                imageView.tintColor = tintColor
                let view = UIView(frame : CGRect(x: 0, y: 0, width: 25, height: 20))
                view.addSubview(imageView)
                leftView = view
            }else {
                leftViewMode = .never
            }

        }
    }

    @IBInspectable var placeholderColor : UIColor? {
        didSet {
            let rawString = attributedPlaceholder?.string != nil ? attributedPlaceholder!.string : ""
            let str = NSAttributedString(string: rawString, attributes: [NSForegroundColorAttributeName : placeholderColor!])
            attributedPlaceholder = str
        }
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: 50, dy: 5)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: 50, dy: 5)
    }

}
Abhishek Biswas
fuente
3

ingrese la descripción de la imagen aquí
Otra forma de establecer el icono de marcador de posición y establecer el relleno en TextField.

let userIcon = UIImage(named: "ImageName") 
setPaddingWithImage(image: userIcon, textField: txtUsername)

func setPaddingWithImage(image: UIImage, textField: UITextField){
    let imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFit
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: 50))
    imageView.frame = CGRect(x: 13.0, y: 13.0, width: 24.0, height: 24.0)
    //For Setting extra padding other than Icon.
    let seperatorView = UIView(frame: CGRect(x: 50, y: 0, width: 10, height: 50))
    seperatorview.backgroundColor = UIColor(red: 80/255, green: 89/255, blue: 94/255, alpha: 1)
    view.addSubview(seperatorView)
    textField.leftViewMode = .always
    view.addSubview(imageView)
    view.backgroundColor = .darkGray
    textField.leftViewMode = UITextFieldViewMode.always
    textField.leftView = view
}
Sudhi 9135
fuente
3

2020 - solución razonable

Respecto a esta locura de Apple.

Esta es quizás la forma más "clara" y sencilla de hacerlo:

ingrese la descripción de la imagen aquí

Primero, debes mover correctamente el texto.

Tenga en cuenta este control de calidad crítico: https://stackoverflow.com/a/27066764/294884

class TidyTextField: UITextField {
    
    @IBInspectable var leftImage: UIImage? = nil
    @IBInspectable var leftPadding: CGFloat = 0
    @IBInspectable var gapPadding: CGFloat = 0
    
    private var textPadding: UIEdgeInsets {
        let p: CGFloat = leftPadding + gapPadding + (leftView?.frame.width ?? 0)
        return UIEdgeInsets(top: 0, left: p, bottom: 0, right: 5)
    }
    
    override open func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: textPadding)
    }
    
    override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: textPadding)
    }
    
    override open func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.inset(by: textPadding)
    }
    

Continuando, ahora tenemos que hacer y mover la imagen de la izquierda:

    override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
        var r = super.leftViewRect(forBounds: bounds)
        r.origin.x += leftPadding
        return r
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }
    
    private func setup() {
        if let image = leftImage {
            if leftView != nil { return } // critical!
            
            let im = UIImageView()
            im.contentMode = .scaleAspectFit
            im.image = image
            
            leftViewMode = UITextField.ViewMode.always
            leftView = im
            
        } else {
            leftViewMode = UITextField.ViewMode.never
            leftView = nil
        }
    }
}

Esta parece ser la forma más clara y confiable de hacerlo.

Fattie
fuente
2

Swift 3.1

extension UITextField
{
    enum Direction
    {
        case Left
        case Right
    }

    func AddImage(direction:Direction,imageName:String,Frame:CGRect,backgroundColor:UIColor)
    {
        let View = UIView(frame: Frame)
        View.backgroundColor = backgroundColor

        let imageView = UIImageView(frame: Frame)
        imageView.image = UIImage(named: imageName)

        View.addSubview(imageView)

        if Direction.Left == direction
        {
            self.leftViewMode = .always
            self.leftView = View
        }
        else
        {
            self.rightViewMode = .always
            self.rightView = View
        }
    }

}
jethava yogesh
fuente
Por favor, agregue el uso y lo que necesito para pasar el parámetro de marco.
Surya Reddy
en esta función Parámetro "Marco" Uso para vista izquierda o derecha
jethava yogesh
1

Puede poner esta función en su archivo global o por encima de su clase para que pueda acceder a ella en toda la aplicación. Después de este procedimiento, puede llamar a esta función según sus requisitos en la aplicación.

        func SetLeftSIDEImage(TextField: UITextField, ImageName: String){

                let leftImageView = UIImageView()
                leftImageView.contentMode = .scaleAspectFit

                let leftView = UIView()

                leftView.frame = CGRect(x: 20, y: 0, width: 30, height: 20)
                leftImageView.frame = CGRect(x: 13, y: 0, width: 15, height: 20)
                TextField.leftViewMode = .always
                TextField.leftView = leftView

                let image = UIImage(named: ImageName)?.withRenderingMode(.alwaysTemplate)
                leftImageView.image = image
                leftImageView.tintColor = UIColor(red: 106/255, green: 79/255, blue: 131/255, alpha: 1.0)
                leftImageView.tintColorDidChange()

                leftView.addSubview(leftImageView)
            }

            SetLeftSIDEImage(TextField: Your_textField, ImageName:YourImageName) // call function
Dhaval Solanki
fuente
2
Bienvenido a StackOverflow, ¿hay alguna forma de que pueda proporcionar alguna explicación junto con este código? Las respuestas que solo contienen código tienden a eliminarse por ser de baja calidad. Por favor, también eche un vistazo a esta guía para responder en la sección de ayuda: stackoverflow.com/help/how-to-answer
Graham
0

¿Por qué no opta por el enfoque más fácil? Para la mayoría de los casos, desea agregar íconos como fuente impresionante ... Simplemente use la biblioteca de fuente impresionante y sería tan fácil agregar un ícono a un campo de texto como este:

myTextField.setLeftViewFAIcon(icon: .FAPlus, leftViewMode: .always, textColor: .red, backgroundColor: .clear, size: nil)

Debería instalar primero esta biblioteca rápida: https://github.com/Vaberer/Font-Awesome-Swift

Alex Zanfir
fuente
5
¿Por qué debería uno agregar una biblioteca completa solo para obtener un glifo?
0

Esta es una versión modificada de la respuesta de Mark Moeykens con un relleno adicional entre la imagen y el texto y un tamaño de imagen ajustable en caso de que alguien lo necesite.

Rápido 4

    import UIKit

    @IBDesignable
    class TextFieldWithImage: UITextField {

        override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
            return super.leftViewRect(forBounds: bounds)
        }

        @IBInspectable var leftImage: UIImage? {
            didSet {
                updateView()
            }
        }
        @IBInspectable var leftPadding: CGFloat = 0 {
            didSet {
                updateView()
            }
        }
        @IBInspectable var rightPadding: CGFloat = 0 {
            didSet {
                updateView()
            }
        }
        @IBInspectable var imageMaxHeight: CGFloat = 0 {
            didSet {
                updateView()
            }
        }

        @IBInspectable var color: UIColor = UIColor.lightGray {
            didSet {
                updateView()
            }
        }

        func updateView() {
            if let image = leftImage {
                leftViewMode = UITextField.ViewMode.always

                let containerSize = calculateContainerViewSize(for: image)
                let containerView = UIView(frame: CGRect(x: 0, y: 0, width: containerSize.width, height: containerSize.height))

                let imageView = UIImageView(frame: .zero)
                containerView.addSubview(imageView)
                setImageViewConstraints(imageView, in: containerView)

                setImageViewProperties(imageView, image: image)

                leftView = containerView
            } else {
                leftViewMode = UITextField.ViewMode.never
                leftView = nil
            }

            attributedPlaceholder = NSAttributedString(string: placeholder != nil ? placeholder! : "",
                    attributes: [NSAttributedString.Key.foregroundColor: color])
        }

        private func calculateContainerViewSize(for image: UIImage) -> CGSize {
            let imageRatio = image.size.height / image.size.width
            let adjustedImageMaxHeight = imageMaxHeight > self.frame.height ? self.frame.height : imageMaxHeight

            var imageSize = CGSize()
            if image.size.height > adjustedImageMaxHeight {
                imageSize.height = adjustedImageMaxHeight
                imageSize.width = imageSize.height / imageRatio
            }

            let paddingWidth = leftPadding + rightPadding

            let containerSize = CGSize(width: imageSize.width + paddingWidth, height: imageSize.height)
            return containerSize
        }

        private func setImageViewConstraints(_ imageView: UIImageView, in containerView: UIView) {
            imageView.translatesAutoresizingMaskIntoConstraints = false
            imageView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
            imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
            imageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -rightPadding).isActive = true
            imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: leftPadding).isActive = true
        }

        private func setImageViewProperties(_ imageView: UIImageView, image: UIImage) {
            imageView.contentMode = .scaleAspectFit
            imageView.image = image
            imageView.tintColor = color
        }
    }
l.sypniewski
fuente
0

Rápido 5

Similar a @Markus, pero en Swift 5 :

emailTextField.leftViewMode = UITextField.ViewMode.always
emailTextField.leftViewMode = .always
Jerry Chong
fuente
0

SwiftUI

RoundedRectangle(cornerRadius: 50)
                .frame(height: 40)
                .colorInvert() // sets the background white
            .padding()
            .shadow(radius: 12) // adds shadow to the rectangle
                .overlay(
                    HStack(spacing: 20){

                        Image(systemName: "person")
                            .resizable()
                            .aspectRatio(contentMode: .fit)

                        TextField("Username ", text: $username)
                            .font(Font.custom("Arial", size: 25))


                            .font(.title)
                    }
                    .padding()
                    .padding()
                )

Resultados

Roberto Font
fuente
0

Usando la extensión en Swift4, podemos colocar fácilmente la imagen a la derecha oa la izquierda con relleno en TextField.

extension UITextField {

    //MARK:- Set Image on the right of text fields

  func setupRightImage(imageName:String){
    let imageView = UIImageView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
    imageView.image = UIImage(named: imageName)
    let imageContainerView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 55, height: 40))
    imageContainerView.addSubview(imageView)
    rightView = imageContainerView
    rightViewMode = .always
    self.tintColor = .lightGray
}

 //MARK:- Set Image on left of text fields

    func setupLeftImage(imageName:String){
       let imageView = UIImageView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
       imageView.image = UIImage(named: imageName)
       let imageContainerView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 55, height: 40))
       imageContainerView.addSubview(imageView)
       leftView = imageContainerView
       leftViewMode = .always
       self.tintColor = .lightGray
     }

  }

Use el código como para la configuración de la imagen izquierda: -

   self.password_text_field.setupLeftImage(imageName: "unlock")

Salida :)

ingrese la descripción de la imagen aquí

Ashutosh kumar Mishra
fuente