Как вставить изображение Inline UILabel в iOS 8 с помощью swift

Я следил за следующим сообщением о том, как использовать NSTextAttachment для добавления встроенных изображений. с вашими UILabels. Я сделал все, что мог, и написал свою версию на Swift.

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

var beerName:String!

        if(sender == bn_beer1)
        {
            beerName = "beer1.png"
        }

        if(sender == bn_beer2)
        {
            beerName = "beer2.png"
        }

        if(sender == bn_beer3)
        {
            beerName = "beer3"
        }



        var attachment:NSTextAttachment = NSTextAttachment()
        attachment.image = UIImage(named: beerName)


        var attachmentString:NSAttributedString = NSAttributedString(attachment: attachment)
        var myString:NSMutableAttributedString = NSMutableAttributedString(string: inputField.text)
        myString.appendAttributedString(attachmentString)



        inputField.attributedText = myString;

person mattwallace    schedule 04.11.2014    source источник
comment
Какой размер изображения?   -  person Larme    schedule 05.11.2014


Ответы (4)


Это не работает с UITextField. Он работает только на UILabel.

Вот расширение UILabel на основе вашего кода (Swift 2.0)

extension UILabel
{
    func addImage(imageName: String)
    {
        let attachment:NSTextAttachment = NSTextAttachment()
        attachment.image = UIImage(named: imageName)

        let attachmentString:NSAttributedString = NSAttributedString(attachment: attachment)
        let myString:NSMutableAttributedString = NSMutableAttributedString(string: self.text!)
        myString.appendAttributedString(attachmentString)

        self.attributedText = myString
    }
}

РЕДАКТИРОВАТЬ:

вот новая версия, которая позволяет добавлять значок до или после метки. Так же есть функция убрать иконку с метки

extension UILabel
{
    func addImage(imageName: String, afterLabel bolAfterLabel: Bool = false)
    {
        let attachment: NSTextAttachment = NSTextAttachment()
        attachment.image = UIImage(named: imageName)
        let attachmentString: NSAttributedString = NSAttributedString(attachment: attachment)

        if (bolAfterLabel)
        {
            let strLabelText: NSMutableAttributedString = NSMutableAttributedString(string: self.text!)
            strLabelText.appendAttributedString(attachmentString)

            self.attributedText = strLabelText
        }
        else
        {
            let strLabelText: NSAttributedString = NSAttributedString(string: self.text!)
            let mutableAttachmentString: NSMutableAttributedString = NSMutableAttributedString(attributedString: attachmentString)
            mutableAttachmentString.appendAttributedString(strLabelText)

            self.attributedText = mutableAttachmentString
        }
    }

    func removeImage()
    {
        let text = self.text
        self.attributedText = nil
        self.text = text
    }
}
person Regis St-Gelais    schedule 28.09.2015
comment
Если вы планируете добавить несколько изображений, не забудьте изменить инициализатор с let strLabelText: NSAttributedString = NSAttributedString(string: self.text!) на: let strLabelText: NSMutableAttributedString = NSMutableAttributedString(attributedString: self.attributedText!) - person Hernan Arber; 28.02.2017
comment
@HernanArber, как вы реализуете несколько изображений? - person Coder221; 29.04.2019

Расширенный ответ Regis St-Gelais для Swift 3 и Swift 4 и без принудительной распаковки:

extension UILabel {

    func addImageWith(name: String, behindText: Bool) {

        let attachment = NSTextAttachment()
        attachment.image = UIImage(named: name)
        let attachmentString = NSAttributedString(attachment: attachment)

        guard let txt = self.text else {
            return
        }

        if behindText {
            let strLabelText = NSMutableAttributedString(string: txt)
            strLabelText.append(attachmentString)
            self.attributedText = strLabelText
        } else {
            let strLabelText = NSAttributedString(string: txt)
            let mutableAttachmentString = NSMutableAttributedString(attributedString: attachmentString)
            mutableAttachmentString.append(strLabelText)
            self.attributedText = mutableAttachmentString
        }
    }

    func removeImage() {
        let text = self.text
        self.attributedText = nil
        self.text = text
    }
}

Применение:

self.theLabel.text = "desiredText"
self.theLabel.addImageWith(name: "nameOfImage", behindText: false)
person David Seek    schedule 26.06.2017
comment
Как установить положение изображения и текста? Они отображаются, чтобы закрыть. - person Krutika Sonawala; 03.07.2018

Редактировать 19/03/18: Исправить ошибку, когда imageBehindText = false + Размер изображения в пикселях не имеет значения.

Обновление функции Дэвида для нескольких изображений с сохранением текста и размером изображения в зависимости от размера шрифта (Swift 4):

extension UILabel {
    /**
     This function adding image with text on label.

     - parameter text: The text to add
     - parameter image: The image to add
     - parameter imageBehindText: A boolean value that indicate if the imaga is behind text or not
     - parameter keepPreviousText: A boolean value that indicate if the function keep the actual text or not
     */
    func addTextWithImage(text: String, image: UIImage, imageBehindText: Bool, keepPreviousText: Bool) {
                    let lAttachment = NSTextAttachment()
        lAttachment.image = image

        // 1pt = 1.32px
        let lFontSize = round(self.font.pointSize * 1.32)
        let lRatio = image.size.width / image.size.height

        lAttachment.bounds = CGRect(x: 0, y: ((self.font.capHeight - lFontSize) / 2).rounded(), width: lRatio * lFontSize, height: lFontSize)

        let lAttachmentString = NSAttributedString(attachment: lAttachment)

        if imageBehindText {
            let lStrLabelText: NSMutableAttributedString

            if keepPreviousText, let lCurrentAttributedString = self.attributedText {
                lStrLabelText = NSMutableAttributedString(attributedString: lCurrentAttributedString)
                lStrLabelText.append(NSMutableAttributedString(string: text))
            } else {
                lStrLabelText = NSMutableAttributedString(string: text)
            }

            lStrLabelText.append(lAttachmentString)
            self.attributedText = lStrLabelText
        } else {
            let lStrLabelText: NSMutableAttributedString

            if keepPreviousText, let lCurrentAttributedString = self.attributedText {
                lStrLabelText = NSMutableAttributedString(attributedString: lCurrentAttributedString)
                lStrLabelText.append(NSMutableAttributedString(attributedString: lAttachmentString))
                lStrLabelText.append(NSMutableAttributedString(string: text))
            } else {
                lStrLabelText = NSMutableAttributedString(attributedString: lAttachmentString)
                lStrLabelText.append(NSMutableAttributedString(string: text))
            }

            self.attributedText = lStrLabelText
        }
    }

    func removeImage() {
        let text = self.text
        self.attributedText = nil
        self.text = text
    }
}
person Jordan Favray    schedule 13.03.2018
comment
Как добавить пробел для разделения изображения и текста.? (Это работает, но изображение прилипает к тексту) - person Mario Burga; 30.11.2019
comment
Просто нужно добавить границу в lAttachment - person Jordan Favray; 05.12.2019

Используйте это расширение ниже, оно точно сработает

 extension NSMutableAttributedString { 
   static func addImageInBetweenString(firstSentence: String, image: UIImage?, lastSentence: String) -> NSMutableAttributedString {
     // create an NSMutableAttributedString that we'll append everything to
     let fullString = NSMutableAttributedString(string: firstSentence)

     // create our NSTextAttachment
     let image1Attachment = NSTextAttachment()
     image1Attachment.image = image
     //image1Attachment.setImageHeight(height: 15.0)
     Image1Attachment.bounds = CGRect(x: 0, y: -5, width: 15, height: 15)

     // wrap the attachment in its own attributed string so we can append it
     let image1String = NSAttributedString(attachment: image1Attachment)

    // add the NSTextAttachment wrapper to our full string, then add some more text.
    fullString.append(image1String)
    fullString.append(NSAttributedString(string: lastSentence))

    return fullString
   }
} 



extension NSTextAttachment {
   func setImageHeight(height: CGFloat) {
      guard let image = image else { return }
      let ratio = image.size.width / image.size.height
      bounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: ratio * height, height: height)
  }
 }
person Purnendu roy    schedule 20.10.2020