Swift在UITextField中添加图标/图片

127

我想在UITextField中添加图标/图片。该图标/图片应位于占位符左侧。

在此输入图片描述

我尝试过这个:

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

谢谢。


91
你不小心加了分号 :D - Gerald
11
emailField.leftView = UIImageView(image: UIImage(named: "search")) 可以翻译为:将邮箱输入框的左侧视图设置为一张搜索图片,该图片加载自名为"search"的图片资源。 - tspentzas
使用@IBDesignable,我们可以以优雅的方式完成此操作,就像这个例子中所示: https://dev59.com/Qa3la4cB1Zd3GeqPP6NG#51841433 - Rizwan
21个回答

141

Sahil有一个很好的答案,我想将其扩展为@IBDesignable,以便开发人员可以在Storyboard中向他们的UITextFields添加图像。

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

这里正在发生什么?

这个可设计的部件允许你:

  • 在左侧设定一张图片
  • 在UITextField的左边缘和图片之间添加填充
  • 设置颜色使图片和占位符文本匹配

注释

  • 要改变图片颜色,必须按照代码注释中的说明进行操作
  • 图片颜色不会在Storyboard中改变,您需要运行项目在模拟器/设备上查看颜色。

在Storyboard中设计 Storyboard

运行时 Runtime


5
为避免图像被重新调整大小,添加了 imageView.contentMode = .AspectFit。 - Jerland2
3
非常感谢您发布了这篇优秀的文章!我已经进行了修改,使其具备了从右到左的选项。代码在这里可以获取:http://pastebin.com/7CCm6NEB。 - Ali Almohsen
@Ali Almohsen,我们不需要编写额外的代码来将图像放置在右侧。您可以在界面生成器中的语义选项中选择“强制从右到左”选项,以使图像位于正确位置。 - Sahil
18
图片和文本之间需要留白吗? - Zaporozhchenko Oleksandr
1
伟大的答案。 - Ripa Saha
显示剩余6条评论

137

尝试添加emailField.leftViewMode = UITextFieldViewMode.Always

(默认的leftViewModeNever)

Swift 4的更新答案

emailField.leftViewMode = UITextFieldViewMode.always

emailField.leftViewMode = .always

1
这是我的' ViewWillAppear '部分的完整代码:' var imageView = UIImageView(); var image = UIImage(named: "email.png"); imageView.image = image; emailTextField.leftView = imageView; emailTextField.leftViewMode = UITextFieldViewMode.Always - informatiker
4
好的,问题在于图标是白色的,在白色背景上不可见。 - informatiker
@Markus:嘿,我正在使用相同的代码,但它没有显示图像?你有什么解释吗? - Sashi
@Sashi,不是真的...请确保通过在另一个“UIImageView”中加载图像来加载它(并且它不是白色背景上的白色)。 - Markus
7
我继续搜索并最终让它正常工作了,我错过了为图像视图设置框架的步骤。看起来在将图像添加到uitextfield之前,我们需要设置图像的框架。例如:imageView1.frame = CGRect(x: 5, y: 0, width: userName.frame.height, height: userName.frame.height) view.addSubview(imageView1) - Sashi
显示剩余3条评论

58

我只是想在这里添加一些内容:

如果你想在 UITextField 的左侧添加图片,使用 UITextFieldleftView 属性。

注意: 不要忘记设置左侧视图模式 leftViewModeUITextFieldViewMode.Always,右侧则为 rightViewMode,默认值为 UITextFieldViewModeNever

例如:

要在左侧添加图片

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

如何在右侧添加图片

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

注意:UITextField的左侧或右侧添加图像时,需要注意以下几点:

  • 不要忘记为将要添加到UITextField上的ImageView指定一个框架。

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

  • 如果您的图像背景是白色,则图像将不会在UITextField上显示。

  • 如果您想将图像添加到特定位置,则需要将ImageView作为UITextField的子视图添加。

Swift 3.0更新

@Mark Moeykens美化了它并将其设置为@IBDesignable

我进行了修改并添加了一些新功能(添加底部线和右边图像的填充)。

注意:如果您想在右侧添加图像,则可以在界面构建器中的“语义”选项中选择Force Right-to-Left选项(但对于右侧图像填充,直到您覆盖rightViewRect方法才能起作用)。

输入图像描述

我对此进行了修改,并可以从此处下载源代码ImageTextField

输入图像描述


我该如何将这个添加到扩展中并在我的视图控制器中调用?你能给我建议吗? - narahari_arjun
非常简单!只需在UIViewController扩展中创建函数,并在调用该函数时传递imagename和textfield引用即可。 - Sahil
扩展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 } } 并像这样调用它 self.addLeftImage("imganame", textField: yourtextfield) - Sahil
我尝试改变图标位置,但使用这段代码没有改变。 - Protocol

28

UITextField带有左侧或右侧图像

受之前的帖子启发,我们可以创建一个扩展程序。

我们可以将图像放在右侧或左侧。

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
}

}

使用:

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

享受 :)


2
你让我很开心,我自定义了“view.backgroundColor”和“imageView.tintColor”,使其完全可定制化。非常感谢你的回答 xD - Andres Paladines
2
这太棒了。 - Mohamed Haseel
2
这是最好和简单的答案。 - Gerardo Salazar Sánchez

18

为了创建填充,我喜欢将图像放在容器视图内。一旦您对图标位置感到满意,就可以删除背景颜色。

输入图片描述

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

谢谢。用颜色进行了很好的解释。 - Hamid Reza Ansari
最聪明的方法是在UITextfield上不使用扩展名来缩短。 - Waseem05

13

如何在Swift 3.0中将图像添加到文本框左侧

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

10

Swift 5

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

我已经创建了扩展。
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
  }
}

结果

这里输入图片描述


8

2020 - 明智解决方案

针对苹果公司的这种疯狂行为。

这里也许是最"清晰"、最简单的方法:

在此输入图片描述

首先,您必须正确地移动文本。

注意这个关键的QA:https://dev59.com/t18e5IYBdhLWcg3wyM0r#27066764

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

接着,我们现在需要制作并移动左侧的图像:

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

这似乎是最清晰、最可靠的方法。


7
使用Swift4的扩展,我们可以轻松地将带有填充的图像放在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
     }

  }

使用以下代码设置左侧图像:

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

输出 :)

在这里输入图片描述


1
在我看来,这是最好的方法。不需要故事板。简单明了。干得好! - Didami
优秀的工作...... - M Hamayun zeb

3

在此输入图像描述
另一种设置文本框占位符图标并设置填充的方法。

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接