Cómo incrustar un ícono pequeño en UILabel

153

Necesito incrustar pequeños íconos (una especie de viñetas personalizadas) en mi UILabeliOS7. ¿Cómo puedo hacer esto en el diseñador de interfaces? O al menos en código?

En Android hay leftDrawabley rightDrawablepara etiquetas, pero ¿cómo se hace en iOS? Muestra en android:

muestra de Android

AVEbrahimi
fuente
No estoy familiarizado con Android, ¿puedes publicar alguna imagen como referencia?
user1673099
2
crear una pequeña vista de imagen y agregarla como subvista al objeto de la etiqueta
Saurabh Passolia

Respuestas:

292

Puede hacerlo con los archivos adjuntos de texto de iOS 7 , que son parte de TextKit. Algún código de muestra:

NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"MyIcon.png"];

NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];

NSMutableAttributedString *myString= [[NSMutableAttributedString alloc] initWithString:@"My label text"];
[myString appendAttributedString:attachmentString];

myLabel.attributedText = myString;
Scott Berrevoets
fuente
¿Qué tal iOS6? ¿¿Tienes alguna sugerencia?? Thx
Steven Jiang
1
@StevenJiang: Tendrás que agregar un UIImageViewa tu etiqueta
Scott Berrevoets
1
Lamentablemente, esto coloca el icono después del texto. ¿Hay alguna posibilidad de que podamos mover esto antes del texto porque no puedo encontrar una manera?
reVerse
44
@reVerse En lugar de agregar la imagen (cadena de archivo adjunto) a su cadena de texto, puede intentarlo al revés, agregando la cadena de texto a la cadena de archivo adjunto.
Scott Berrevoets
11
Ya probé esto ayer. Parece algo perdido porque ahora funciona. Gracias. Por si acaso para todos los que están tratando de lograr lo mismo (ya que es un poco diferente): NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; NSMutableAttributedString *myString = [[NSMutableAttributedString alloc] initWithAttributedString:attachmentString]; NSAttributedString *myText = [[NSMutableAttributedString alloc] initWithString:text]; [myString appendAttributedString:myText];
reVerse
153

Aquí está la forma de incrustar el icono en UILabel.

También para alinear el ícono use attach.bounds


Swift 5.1

// Create Attachment
let imageAttachment = NSTextAttachment()
imageAttachment.image = UIImage(named:"iPhoneIcon")
// Set bound to reposition
let imageOffsetY: CGFloat = -5.0
imageAttachment.bounds = CGRect(x: 0, y: imageOffsetY, width: imageAttachment.image!.size.width, height: imageAttachment.image!.size.height)
// Create string with attachment
let attachmentString = NSAttributedString(attachment: imageAttachment)
// Initialize mutable string
let completeText = NSMutableAttributedString(string: "")
// Add image to mutable string
completeText.append(attachmentString)
// Add your text to mutable string
let textAfterIcon = NSAttributedString(string: "Using attachment.bounds!")
completeText.append(textAfterIcon)
self.mobileLabel.textAlignment = .center
self.mobileLabel.attributedText = completeText

Versión Objective-C

NSTextAttachment *imageAttachment = [[NSTextAttachment alloc] init];
imageAttachment.image = [UIImage imageNamed:@"iPhoneIcon"];
CGFloat imageOffsetY = -5.0;
imageAttachment.bounds = CGRectMake(0, imageOffsetY, imageAttachment.image.size.width, imageAttachment.image.size.height);
NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:imageAttachment];
NSMutableAttributedString *completeText = [[NSMutableAttributedString alloc] initWithString:@""];
[completeText appendAttributedString:attachmentString];
NSAttributedString *textAfterIcon = [[NSAttributedString alloc] initWithString:@"Using attachment.bounds!"];
[completeText appendAttributedString:textAfterIcon];
self.mobileLabel.textAlignment = NSTextAlignmentRight;
self.mobileLabel.attributedText = completeText;

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Tarun Seera
fuente
22
Vote por archivos adjuntos
Peter Zhao
3
Gran llamada sobre el uso de archivos adjuntos. Eso es exactamente lo que estaba buscando.
Geoherna
2
De hecho, el imageOffsetY se puede calcular en lugar de usar un valor fijo de -5.0. let imageOffsetY: CGFloat = - (imageAttachment.image! .size.height - self.mobileLabel.font.pointSize) / 2.0;
JonSlowCN
Nota: ralentiza el tiempo de compilación
Jack
¿Puedo hacerlo en storyboard?
Augusto
53

Swift 4.2:

let attachment = NSTextAttachment()        
attachment.image = UIImage(named: "yourIcon.png")
let attachmentString = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: price)
myString.append(attachmentString)
label.attributedText = myString
André Dos Santos
fuente
23

Su imagen de referencia se parece a un botón. Probar (también se puede hacer en Interface Builder):

ingrese la descripción de la imagen aquí

UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(50, 50, 100, 44)];
[button setImage:[UIImage imageNamed:@"img"] forState:UIControlStateNormal];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, -30, 0, 0)];
[button setTitle:@"Abc" forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor yellowColor]];
[view addSubview:button];
Algún chico
fuente
Bien explicado, me gusta el hecho de que te tomaste el tiempo para proporcionar una referencia. ¡Me ayudó mucho! Gracias
Shinnyx
Esto ayudó a poner mi ícono de trofeo en un botón. ¡Muchas gracias!
Harish
23

Versión Swift 3

let attachment = NSTextAttachment()
attachment.image = UIImage(named: "plus")
attachment.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
let attachmentStr = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: "")
myString.append(attachmentStr)
let myString1 = NSMutableAttributedString(string: "My label text")
myString.append(myString1)
lbl.attributedText = myString

Extensión UILabel

extension UILabel {

    func set(text:String, leftIcon: UIImage? = nil, rightIcon: UIImage? = nil) {

        let leftAttachment = NSTextAttachment()
        leftAttachment.image = leftIcon
        leftAttachment.bounds = CGRect(x: 0, y: -2.5, width: 20, height: 20)
        if let leftIcon = leftIcon {
            leftAttachment.bounds = CGRect(x: 0, y: -2.5, width: leftIcon.size.width, height: leftIcon.size.height)
        }
        let leftAttachmentStr = NSAttributedString(attachment: leftAttachment)

        let myString = NSMutableAttributedString(string: "")

        let rightAttachment = NSTextAttachment()
        rightAttachment.image = rightIcon
        rightAttachment.bounds = CGRect(x: 0, y: -5, width: 20, height: 20)
        let rightAttachmentStr = NSAttributedString(attachment: rightAttachment)


        if semanticContentAttribute == .forceRightToLeft {
            if rightIcon != nil {
                myString.append(rightAttachmentStr)
                myString.append(NSAttributedString(string: " "))
            }
            myString.append(NSAttributedString(string: text))
            if leftIcon != nil {
                myString.append(NSAttributedString(string: " "))
                myString.append(leftAttachmentStr)
            }
        } else {
            if leftIcon != nil {
                myString.append(leftAttachmentStr)
                myString.append(NSAttributedString(string: " "))
            }
            myString.append(NSAttributedString(string: text))
            if rightIcon != nil {
                myString.append(NSAttributedString(string: " "))
                myString.append(rightAttachmentStr)
            }
        }
        attributedText = myString
    }
}
RajeshKumar R
fuente
17

He realizado una implementación de esta función en Swift aquí: https://github.com/anatoliyv/SMIconLabel

El código es lo más simple posible:

var labelLeft = SMIconLabel(frame: CGRectMake(10, 10, view.frame.size.width - 20, 20))
labelLeft.text = "Icon on the left, text on the left"

// Here is the magic
labelLeft.icon = UIImage(named: "Bell") // Set icon image
labelLeft.iconPadding = 5               // Set padding between icon and label
labelLeft.numberOfLines = 0             // Required
labelLeft.iconPosition = SMIconLabelPosition.Left // Icon position
view.addSubview(labelLeft)

Así es como se ve:

Imagen de SMIconLabel

anatoliy_v
fuente
13

UIlabelExtensión Swift 4 para agregar imagen a la etiqueta con referencia a las respuestas anteriores

extension UILabel {
  func set(image: UIImage, with text: String) {
    let attachment = NSTextAttachment()
    attachment.image = image
    attachment.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
    let attachmentStr = NSAttributedString(attachment: attachment)

    let mutableAttributedString = NSMutableAttributedString()
    mutableAttributedString.append(attachmentStr)

    let textString = NSAttributedString(string: text, attributes: [.font: self.font])
    mutableAttributedString.append(textString)

    self.attributedText = mutableAttributedString
  }
}
Agente Smith
fuente
NSAttributedString(string: " " + text, attributes: [.font: self.font])
Farzad
@grizzly ¿es eso para crear espacio entre el icono y el texto?
Agente Smith
si. Cuál es otra forma de espacio entre el icono y el texto?
Farzad
4

Versión Swift 2.0:

//Get image and set it's size
let image = UIImage(named: "imageNameWithHeart")
let newSize = CGSize(width: 10, height: 10)

//Resize image
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let imageResized = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

//Create attachment text with image
var attachment = NSTextAttachment()
attachment.image = imageResized
var attachmentString = NSAttributedString(attachment: attachment)
var myString = NSMutableAttributedString(string: "I love swift ")
myString.appendAttributedString(attachmentString)
myLabel.attributedText = myString
Phil
fuente
3

Intenta arrastrar un UIViewa la pantalla en IB. Desde allí se puede arrastrar una UIImageViewy UILabelen la vista que acaba de crear. Establezca la imagen del UIImageViewen el inspector de propiedades como la imagen de viñeta personalizada (que deberá agregar a su proyecto arrastrándola al panel de navegación) y podrá escribir algo de texto en la etiqueta.

nanothread59
fuente
2

intenta de esta manera ...

  self.lbl.text=@"Drawble Left";
    UIImageView *img=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
    img.image=[UIImage imageNamed:@"Star.png"];
    [self.lbl addSubview:img];
usuario1673099
fuente
¿Esto es útil para ti?
user1673099
este enfoque pierde el desplazamiento del texto para la imagen (el texto se encuentra detrás de la imagen)
brigadir
2

Swift 5 Easy Way Simplemente copia y pega lo que quieras

let fullString = NSMutableAttributedString(string:"To start messaging contacts who have Talklo, tap ")

 // create our NSTextAttachment
let image1Attachment = NSTextAttachment() 
image1Attachment.image = UIImage(named: "chatEmoji")
image1Attachment.bounds = CGRect(x: 0, y: -8, width: 25, height: 25)

// 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:" at the right bottom of your screen"))

 // draw the result in a label
 self.lblsearching.attributedText = fullString

ingrese la descripción de la imagen aquí

Shakeel Ahmed
fuente
1

En Swift 2.0,

Mi solución al problema es una combinación de un par de respuestas a esta pregunta. El problema que enfrenté en la respuesta de @ Phil fue que no podía cambiar la posición del ícono, y siempre aparecía en la esquina derecha. Y la única respuesta de @anatoliy_v, no pude cambiar el tamaño del icono que quiero agregar a la cadena.

Para que funcione para mí, primero hice una pod 'SMIconLabel'y luego creé esta función:

func drawTextWithIcon(labelName: SMIconLabel, imageName: String, labelText: String!,  width: Int, height: Int) {

        let newSize = CGSize(width: width, height: height)
        let image = UIImage(named: imageName)
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
        let imageResized = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        labelName.text = " \(labelText)"
        labelName.icon = imageResized
        labelName.iconPosition = .Left
    }

Esta solución no solo lo ayudará a colocar la imagen, sino que también le permitirá realizar los cambios necesarios en el tamaño del icono y otros atributos.

Gracias.

Fennec
fuente
1

Extensión Swift 3 UILabel

Consejo: Si necesita algo de espacio entre la imagen y el texto, use uno o dos espacios antes del texto de la etiqueta.

extension UILabel {
    func addIconToLabel(imageName: String, labelText: String, bounds_x: Double, bounds_y: Double, boundsWidth: Double, boundsHeight: Double) {
        let attachment = NSTextAttachment()
        attachment.image = UIImage(named: imageName)
        attachment.bounds = CGRect(x: bounds_x, y: bounds_y, width: boundsWidth, height: boundsHeight)
        let attachmentStr = NSAttributedString(attachment: attachment)
        let string = NSMutableAttributedString(string: "")
        string.append(attachmentStr)
        let string2 = NSMutableAttributedString(string: labelText)
        string.append(string2)
        self.attributedText = string
    }
}
Gary Mansted
fuente
1
Usé esto y funcionó perfectamente. Los otros anteriores en realidad voltearon la imagen al final de la cadena.
mondousage
1
 func atributedLabel(str: String, img: UIImage)->NSMutableAttributedString
{   let iconsSize = CGRect(x: 0, y: -2, width: 16, height: 16)
    let attributedString = NSMutableAttributedString()
    let attachment = NSTextAttachment()
    attachment.image = img
    attachment.bounds = iconsSize
    attributedString.append(NSAttributedString(attachment: attachment))
    attributedString.append(NSAttributedString(string: str))

    return attributedString
} 

Puede usar esta función para agregar imágenes o iconos pequeños a la etiqueta

Ayush Dixit
fuente
Llame a esto en viewdidload ()
Ayush Dixit
let emojisCollection = [UIImage (nombre: "ic_place"), UIImage (nombre: "ic_group"), UIImage (nombre: "ic_analytics")] lbl1.attributedText = atributedLabel (str: "Howath, Dublin", img: emojisCollection [0 ]!) lbl2.attributedText = atributedLabel (str: "Dificultad: 18+", img: emojisCollection [2]!) lbl3.attributedText = atributedLabel (str: "Tamaño máximo del grupo: 10", img: emojisCollection [1]!)
Ayush Dixit
puedes editar tu respuesta original para incluir los comentarios anteriores.
Moondra
0

tienes que hacer un objeto personalizado donde usaste ay UIViewdentro de donde pusiste UIImageViewayUILabel

Mirko Catalano
fuente