Como incorporar um pequeno ícone no UILabel

153

Preciso incorporar pequenos ícones (tipo de marcadores personalizados) no meu UILabelno iOS7. Como posso fazer isso no designer de interface? Ou pelo menos no código?

No Android, existem leftDrawablee rightDrawablepara rótulos, mas como isso é feito no iOS? Amostra no android:

amostra android

AVEbrahimi
fonte
Eu não estou familiarizado com o Android, você pode postar alguma imagem para referência?
user1673099
2
criar um pequeno ImageView e adicioná-lo como subexibição ao objeto do rótulo
Saurabh Passolia

Respostas:

292

Você pode fazer isso com os anexos de texto do iOS 7 , que fazem parte do TextKit. Algum código de exemplo:

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
fonte
E o iOS6? Você tem alguma sugestão?? Thx
Steven Jiang
1
@StevenJiang: Você precisará apenas adicionar um UIImageViewao seu rótulo
Scott Berrevoets 5/14
1
Infelizmente, isso coloca o ícone após o texto. Alguma chance de podermos mover isso antes do texto, porque não consigo encontrar um caminho ?!
reverso
4
@reVerse Em vez de anexar a imagem (string de anexo) à sua string de texto, você pode tentar o contrário, acrescentando a string de texto à string de anexo.
Scott Berrevoets
11
Já tentei isso ontem. Parece algo perdido, porque agora funciona. Obrigado. Apenas no caso para todos que está tentando realizar a mesma (uma vez que é ligeiramente diferente): NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; NSMutableAttributedString *myString = [[NSMutableAttributedString alloc] initWithAttributedString:attachmentString]; NSAttributedString *myText = [[NSMutableAttributedString alloc] initWithString:text]; [myString appendAttributedString:myText];
reverso
153

Aqui está o caminho para incorporar o ícone no UILabel.

Também para alinhar o ícone, use attachment.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

Versão 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;

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Tarun Seera
fonte
22
Vote para attachment.bounds
Peter Zhao
3
Excelente chamada sobre o uso de attachment.bounds. Isso é exatamente o que eu estava procurando.
Geoherna
2
De fato, o imageOffsetY pode ser calculado em vez de usar um valor fixo de -5,0. deixe imageOffsetY: CGFloat = - (imageAttachment.image! .size.height - self.mobileLabel.font.pointSize) / 2.0;
JonSlowCN
Nota: ele diminui o tempo de compilação
Jack
Eu posso fazer isso no 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
fonte
23

Sua imagem de referência se parece com um botão. Tente (também pode ser feito no Interface Builder):

insira a descrição da imagem aqui

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];
SomeGuy
fonte
Bem explicado, eu gosto do fato de você ter tido tempo para fornecer uma ref. Isto me ajudou bastante! Obrigado
Shinnyx
Isso ajudou a colocar meu ícone de troféu em um botão. Muito obrigado!
Harish
23

Versão 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

Extensão 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
fonte
17

Eu fiz uma implementação desse recurso rapidamente aqui: https://github.com/anatoliyv/SMIconLabel

O código é o mais simples possível:

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)

Aqui está como fica:

Imagem SMIconLabel

anatoliy_v
fonte
13

UIlabelExtensão Swift 4 para adicionar imagem ao rótulo com referência às respostas acima

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
fonte
NSAttributedString(string: " " + text, attributes: [.font: self.font])
Farzad
@grizzly é para criar espaço entre o ícone e o texto?
Agent Smith
sim. existe outra maneira de espaço entre ícone e texto?
Farzad
4

Versão 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
fonte
3

Tente arrastar um UIViewpara a tela no IB. A partir daí, você pode arrastar um UIImageViewe UILabelpara a visualização que você acabou de criar. Defina a imagem do UIImageViewinspetor de propriedades como a imagem de marcador personalizada (que você precisará adicionar ao seu projeto arrastando-a para o painel de navegação) e poderá escrever algum texto no rótulo.

nanothread59
fonte
2

tente assim ...

  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];
user1673099
fonte
Isso é útil para você?
user1673099
esta abordagem perde deslocamento para a imagem (mentiras texto atrás de imagens) texto
Brigadir
2

Swift 5 Easy Way Just CopyPaste e mude o que quiser

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

insira a descrição da imagem aqui

Shakeel Ahmed
fonte
1

Você pode usar um UITextField com a propriedade leftView e, em seguida, defina a enabledpropriedade comoNO

Ou use um UIButton esetImage:forControlState

liamnichols
fonte
1

No Swift 2.0,

Minha solução para o problema é uma combinação de algumas respostas sobre essa questão. O problema que encontrei na resposta de @ Phil foi que não conseguia mudar a posição do ícone, e ele sempre aparecia no canto direito. E a resposta de @anatoliy_v, não pude redimensionar o tamanho do ícone que quero anexar à string.

Para fazê-lo funcionar, primeiro fiz uma pod 'SMIconLabel'e depois criei esta função:

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 solução não apenas ajudará você a colocar a imagem, mas também permitirá que você faça as alterações necessárias no tamanho do ícone e em outros atributos.

Obrigado.

Fennec
fonte
1

Extensão do Swift UILabel

Dica: Se você precisar de algum espaço entre a imagem e o texto, use um ou dois espaços antes do rótulo Text.

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
fonte
1
Eu usei isso e funcionou perfeitamente. Os outros acima realmente viram a imagem no final da string.
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
} 

Você pode usar esta função para adicionar imagens ou pequenos ícones ao rótulo

Ayush Dixit
fonte
Chame isso em viewdidload ()
Ayush Dixit
deixe emojisCollection = [UIImage (nomeado: "ic_place"), UIImage (nomeado: "ic_group"), UIImage (nomeado: "ic_analytics")] lbl1.attributedText = atributedLabel (str: "Howath, Dublin", img: emojisCollection [0 ]!) lbl2.attributedText = atributedLabel (str: "Dificuldade: 18+", img: emojisCollection [2]!) lbl3.attributedText = atributedLabel (str: "Tamanho máximo do grupo: 10", img: emojisCollection [1]!)
Ayush Dixit
você pode editar sua resposta original para incluir os comentários acima.
Moondra
0

você tem que criar um objeto personalizado onde você usou um UIViewe dentro de você coloca um UIImageViewe umUILabel

Mirko Catalano
fonte