Swift add icon/image in UITextField

139,531

Solution 1

Try adding emailField.leftViewMode = UITextFieldViewMode.Always

(Default leftViewMode is Never)

Updated Answer for Swift 4

emailField.leftViewMode = UITextFieldViewMode.always

emailField.leftViewMode = .always

Solution 2

Sahil has a great answer and I wanted to take that and expand it into an @IBDesignable so developers can add images to their UITextFields on the Storyboard.

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

What is happening here?

This designable allows you to:

  • Set an image on the left
  • Add padding between the left edge of the UITextField and the image
  • Set a color so the image and the Placeholder text matches

Notes

  • For image color to change you have to follow that note in the comment in the code
  • The image color will not change in the Storyboard. You have to run the project to see the color in the Simulator/device.

Designable in the Storyboard Storyboard

At Runtime Runtime

Solution 3

I Just want to add some more thing here:

If you want to add the image on UITextField on left side use leftView property of UITextField

NOTE: Don't forget to set leftViewMode to UITextFieldViewMode.Always and for right rightViewMode to UITextFieldViewMode.Always anddefault is UITextFieldViewModeNever

for e.g

For adding an image on left side

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

For adding an image on right side

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

NOTE: some things you need to take care while adding an image on UITextField either on the left side or right side.

  • Don't forget to give a frame of ImageView which are you going to add on UITextField

    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))

  • if your image background is white then image won't visible on UITextField

  • if you want to add an image to the specific position you need to add ImageView as the subview of UITextField.

Update For Swift 3.0

@Mark Moeykens Beautifully expended it and make it @IBDesignable.

I modified and added some more features (add Bottom Line and padding for right image) in this.

NOTE if you want to add an image on the right side you can select the Force Right-to-Left option in semantic in interface builder(But for right image padding won't work until you will override rightViewRect method ).

enter image description here

I have modified this and can download the source from here ImageTextField

enter image description here

Solution 4

UITextField with image (left or right)

Another way, inspired from previous posts to make an extension.

We can put the image on the right or on the left

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
}

}

Use :

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

Enjoy :)

Solution 5

To create padding, I like to place the image inside of a container view. You can remove the background color once you are happy with the icon placement.

enter image description here

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
Share:
139,531

Related videos on Youtube

informatiker
Author by

informatiker

Updated on December 15, 2020

Comments

  • informatiker
    informatiker over 3 years

    I would like to add icon/image in UITextField. The icon/image should be left to placeholder.

    enter image description here

    I tried this:

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

    Thanks.

    • Gerald
      Gerald almost 8 years
      You accidentally added semicolons :D
    • tspentzas
      tspentzas about 7 years
      emailField.leftView = UIImageView(image: UIImage(named: "search")) :)
    • Rizwan
      Rizwan almost 4 years
      Using @IBDesignable we can do this in an elegant way as in this example : stackoverflow.com/a/51841433/8238512
  • Markus
    Markus over 9 years
    Hmm it worked for me, did you try it with the updated value (UITextFieldViewMode.Always)? Do you have any idea of what it was that didn't work? (for instance did it compile?)
  • informatiker
    informatiker over 9 years
    This is my whole code in ' ViewWillAppear' section: ' var imageView = UIImageView(); var image = UIImage(named: "email.png"); imageView.image = image; emailTextField.leftView = imageView; emailTextField.leftViewMode = UITextFieldViewMode.Always
  • Markus
    Markus over 9 years
    @informatiker Ok, So are you sure that you have the connections correct, if you for example set the background color of the emailTextField does it really change? And are you sure that the image is there? For example, create an other UIImageView and load the image in that one to verify that that works.
  • informatiker
    informatiker about 9 years
    yes, thanks. The issue was that the icon was white and wasn't visible on white background.
  • Sashi
    Sashi about 9 years
    @Markus : hey, i'm using the same code but it didn't show the image? do you have any exaplanation?
  • Markus
    Markus about 9 years
    @Sashi, not really... make sure that the image can be loaded by loading it in another UIImageView (and that it's not white on a white background)
  • Sashi
    Sashi about 9 years
    I continued my search and finally got it to work, i missed setting up the frame for the image view. Look's like we need to set frame on image before adding it to the uitextfield. Something like this imageView1.frame = CGRect(x: 5, y: 0, width: userName.frame.height, height: userName.frame.height) view.addSubview(imageView1)
  • Gerald
    Gerald almost 8 years
    doesn't the placeholder overlap with the image?
  • narahari_arjun
    narahari_arjun over 7 years
    how can i add this in extensions and call in my viewcontroller ? can you suggest me
  • Sahil
    Sahil over 7 years
    Very simple! simply create function in UIViewController extension and pass imagename and textfield ref when calling that function.
  • Sahil
    Sahil over 7 years
    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 } } and call it like self.addLeftImage("imganame", textField: yourtextfield)
  • Jerland2
    Jerland2 about 7 years
    Added in imageView.contentMode = .AspectFit, to avoid image resizing.
  • Ali Almohsen
    Ali Almohsen about 7 years
    Thanks a lot for the great post! I've modified it to also have a RTL option. Code available here: pastebin.com/7CCm6NEB
  • Mark Moeykens
    Mark Moeykens about 7 years
    Nice job, guys! I had ended up doing the same thing later on too. Ha ha
  • Sahil
    Sahil about 7 years
    @Ali Almohsen we don't need to write extra code for placing image on right side.you can select the Force Right-to-Left option in semantic in interface builder for image on right place.
  • Zaporozhchenko Oleksandr
    Zaporozhchenko Oleksandr almost 7 years
    what about padding between image and text?
  • Admin
    Admin over 6 years
    Why should one add an entire library only to get one glyph?
  • Graham
    Graham over 6 years
    Welcome to StackOverflow, is there some way you could povide some explanation along with this code? Answers that only have code in them tend to get deleted for being low quality. Please also take a look at this guide for answering in the help section: stackoverflow.com/help/how-to-answer
  • User
    User over 6 years
    Otherwise, well this can be used, set padding, a dummy image and the image outside of the textview.
  • Surya Reddy
    Surya Reddy almost 6 years
    please add ussage and what I need to pass frame param ?
  • Andres Paladines
    Andres Paladines almost 6 years
    You made my day, i customized the "view.backgroundColor" and the "imageView.tintColor" to make it full customizable. Thanks a lot for your answer xD
  • jethava yogesh
    jethava yogesh over 5 years
    in this Function "Frame" Parameter Use for left or right View
  • Mohamed Haseel
    Mohamed Haseel about 5 years
    This is awesome
  • Protocol
    Protocol about 5 years
    i tried to change icon position. but not changed using this code
  • Ripa Saha
    Ripa Saha about 5 years
    the Great answer.
  • Gerardo Salazar Sánchez
    Gerardo Salazar Sánchez almost 5 years
    This is best and simple answers
  • Hamid Reza Ansari
    Hamid Reza Ansari about 4 years
    Thank you. Good explanation with colors.
  • Fattie
    Fattie almost 4 years
    There are some problems here. Setting the frame in updateView actually does nothing - iOS overrides it anyway :/
  • Thomas Haas
    Thomas Haas over 3 years
    How can we update this code to what @ZaporozhchenkoOleksandr commented to use the same leftPadding for the text?
  • lissettdm
    lissettdm over 3 years
    Please, provide an explanation about your answer, stackoverflow.com/help/how-to-answer
  • Didami
    Didami over 2 years
    Best way of doing this in my opinion. No need of storyboards. Simple and short. Nice job!
  • M Hamayun zeb
    M Hamayun zeb about 2 years
    Excellent job......
  • Waseem05
    Waseem05 about 2 years
    most intelligent way as it makes shorter without extension on uitextfield
  • Vcubbz
    Vcubbz almost 2 years
    For anyone wondering how to get padding between the image and the placeholder/text, add a UIView with a frame having a larger width, but the same height as the image in updateView(). Then add the imageView as a subview of the container, and set leftView to the container instead of imageView.