Swift добавить значок / изображение в UITextField


102

Я хочу добавить значок / изображение в UITextField. Значок / изображение следует оставить для заполнителя.

введите описание изображения здесь

Я пробовал это:

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

Спасибо.


74
Вы случайно добавили точку с запятой: D
Джеральд

10
emailField.leftView = UIImageView(image: UIImage(named: "search")):)
tspentzas

Используя, @IBDesignableмы можем сделать это элегантным способом, как в этом примере: stackoverflow.com/a/51841433/8238512
Ризван

Ответы:


122

Попробуйте добавить emailField.leftViewMode = UITextFieldViewMode.Always

( По умолчанию leftViewModeэтоNever )

Обновленный ответ для Swift 4

emailField.leftViewMode = UITextFieldViewMode.always

emailField.leftViewMode = .always

Хм, у меня это сработало, вы пробовали с обновленным значением ( UITextFieldViewMode.Always)? Вы хоть представляете, что не сработало? (например, он компилировался?)
Маркус

Это весь мой код в разделе ViewWillAppear: 'var imageView = UIImageView (); var image = UIImage (с именем "email.png"); imageView.image = изображение; emailTextField.leftView = imageView; emailTextField.leftViewMode = UITextFieldViewMode.Always
informatiker

@informatiker Хорошо, вы уверены, что у вас правильные соединения, если вы, например, установите цвет фона, emailTextFieldдействительно ли он меняется? А вы уверены, что изображение есть? Например, создайте другой UIImageView и загрузите imageв него, чтобы убедиться, что он работает.
Маркус

4
Да, спасибо. Проблема заключалась в том, что значок был белым и не был виден на белом фоне.
informatiker

5
Я продолжил поиск и наконец заставил его работать, я пропустил настройку рамки для просмотра изображения. Похоже, нам нужно установить рамку на изображение, прежде чем добавлять его в поле uitext. Примерно такimageView1.frame = CGRect(x: 5, y: 0, width: userName.frame.height, height: userName.frame.height) view.addSubview(imageView1)
Саши 09

125

У Сахила есть отличный ответ, и я хотел использовать его и расширить до @IBDesignable, чтобы разработчики могли добавлять изображения в свои поля 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 и изображением
  • Установите цвет так, чтобы изображение и текст заполнителя соответствовали

Ноты

  • Чтобы изменить цвет изображения, вы должны следовать этому примечанию в комментарии в коде.
  • Цвет изображения в Раскадровке не изменится. Вы должны запустить проект, чтобы увидеть цвет в симуляторе / устройстве.

Возможность проектирования в раскадровке Раскадровка

Во время выполнения Время выполнения


5
Добавлен в imageView.contentMode = .AspectFit, чтобы избежать изменения размера изображения.
Jerland2,

3
Большое спасибо за отличный пост! Я изменил его, чтобы также иметь возможность RTL. Код доступен здесь: pastebin.com/7CCm6NEB
Али Альмохсен

Отличная работа, ребята! Позже я сделал то же самое. Ха-ха
Марк Мойкенс

14
как насчет отступов между изображением и текстом?
Запорожченко Александр

1
Отличный ответ.
Рипа Саха

51

Я просто хочу добавить сюда еще кое-что:

Если вы хотите добавить изображение UITextFieldслева, используйте leftViewсвойствоUITextField

Примечание: Не забудьте набор leftViewModeдля UITextFieldViewMode.Alwaysи права rightViewModeна UITextFieldViewMode.Always andдефолт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с левой или с правой стороны.

  • Не забудьте указать рамку, ImageViewкоторую вы собираетесь добавитьUITextField

    пусть imageView = UIImageView (кадр: CGRect (x: 0, y: 0, ширина: 20, высота: 20))

  • если фон вашего изображения белый, то изображение не будет отображаться на UITextField

  • если вы хотите добавить изображение в определенную позицию, которую необходимо добавить ImageViewв качестве подвида UITextField.

Обновление для Swift 3.0

@Mark Moeykens Красиво расширил его и сделал @IBDesignable .

Я изменил и добавил еще несколько функций (добавьте нижнюю строку и отступ для правого изображения) в этом.

ПРИМЕЧАНИЕ: если вы хотите добавить изображение с правой стороны, вы можете выбрать Force Right-to-Leftопцию в semanticпостроителе интерфейса (но для правого заполнения изображения не будет работать, пока вы не переопределите метод rightViewRect).

введите описание изображения здесь

Я изменил это и могу скачать источник отсюда ImageTextField

введите описание изображения здесь


как я могу добавить это в расширения и вызвать в моем контроллере просмотра? Вы можете мне предложить
narahari_arjun

Очень просто! просто создайте функцию в расширении UIViewController и передайте имя изображения и ссылку на текстовое поле при вызове этой функции.
Sahil

extension UIViewController {func addLeftImage (imageName: String, textField: UITextField) {textField.leftViewMode = UITextFieldViewMode. Всегда позволяйте 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)
Сахил

я попытался изменить положение значка. но не изменен с помощью этого кода
Rahul Phate

22

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

Наслаждаться :)


1
Вы сделали мой день, я настроил "view.backgroundColor" и "imageView.tintColor", чтобы сделать его полностью настраиваемым. Большое спасибо за ваш ответ xD
Andres Paladines

1
Это потрясающе
Мохамед Хасил

1
Это лучшие и простые ответы
Херардо Саласар Санчес

14

Для создания отступов мне нравится помещать изображение внутри представления контейнера. Вы можете удалить цвет фона, когда будете довольны размещением значка.

введите описание изображения здесь

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

Спасибо. Хорошее объяснение с помощью цветов.
Хамид Реза Ансари

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

6

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

Результат

введите описание изображения здесь


4

2020 - разумное решение

По поводу этого безумия от Apple.

Вот, пожалуй, самый «ясный» и простой способ сделать это:

введите описание изображения здесь

Во-первых, необходимо правильно переместить текст.

Обратите внимание на этот критический QA: 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)
    }
    

продолжая, теперь мы должны сделать и переместить левое изображение:

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

Кажется, это самый ясный и надежный способ сделать это.


3

Я создал простой файл IBDesignable. Используйте его, как хотите. Просто подтвердите свой UITextField этому классу.

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

}

3

введите описание изображения здесь
Другой способ установить значок заполнителя и установить отступ в 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
}

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

}

пожалуйста, добавьте ussage и что мне нужно передать параметр кадра?
Surya Reddy

в этой функции Параметр "Рамка" Используйте для левого или правого обзора
jethava yogesh

1

Вы можете поместить эту функцию в свой глобальный файл или выше своего класса, чтобы иметь к нему доступ во всем приложении. После этой процедуры вы можете вызвать эту функцию в соответствии с вашими требованиями в приложении.

        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

2
Добро пожаловать в StackOverflow, есть ли способ дать какое-то объяснение вместе с этим кодом? Ответы, в которых есть только код, как правило, удаляются из-за низкого качества. Также ознакомьтесь с этим руководством, чтобы ответить в разделе справки: stackoverflow.com/help/how-to-answer
Грэм,

0

Почему бы вам не выбрать самый простой подход. В большинстве случаев вы хотите добавить значки, такие как font awesome ... Просто используйте библиотеку font awesome, и было бы так же легко добавить значок в текстовое поле, как это:

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

Вам нужно сначала установить эту быструю библиотеку: https://github.com/Vaberer/Font-Awesome-Swift


5
Почему нужно добавлять целую библиотеку только для того, чтобы получить один глиф?

0

Это модифицированная версия ответа Марка Мойкенса с добавленным отступом между изображением и текстом и регулируемым размером изображения на случай, если это кому-то понадобится.

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


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

Полученные результаты


0

Используя расширение в 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")

Вывод :)

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.