Comment intégrer une petite icône dans UILabel

153

J'ai besoin d'intégrer de petites icônes (sorte de puces personnalisées) à mon UILabeldans iOS7. Comment puis-je faire cela dans le concepteur d'interface? Ou du moins dans le code?

Dans Android, il y a leftDrawableet rightDrawablepour les étiquettes, mais comment cela se fait-il sous iOS? Échantillon dans Android:

échantillon Android

AVEbrahimi
la source
Je ne suis pas familier avec Android, pouvez-vous poster une image pour référence?
user1673099
2
créer une petite vue d'image et l'ajouter comme sous-vue à l'objet de l'étiquette
Saurabh Passolia

Réponses:

292

Vous pouvez le faire avec les pièces jointes de texte d' iOS 7 , qui font partie de TextKit. Quelques exemples de code:

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
la source
Et pour iOS6? Avez-vous une suggestion?? Thx
Steven Jiang
1
@StevenJiang: Vous devrez simplement ajouter un UIImageViewà votre étiquette
Scott Berrevoets
1
Malheureusement, cela place l'icône après le texte. Y a-t-il une chance que nous puissions déplacer ceci avant le texte car je ne trouve pas de moyen?
revoir le
4
@reVerse Au lieu d'ajouter l'image (chaîne de pièce jointe) à votre chaîne de texte, vous pouvez essayer l'inverse, donc en ajoutant la chaîne de texte à la chaîne de pièce jointe.
Scott Berrevoets
11
Déjà essayé hier. On dirait que quelque chose a manqué car maintenant ça marche. Merci. Juste au cas où tous ceux qui essaient d'accomplir la même chose (car c'est légèrement différent): NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; NSMutableAttributedString *myString = [[NSMutableAttributedString alloc] initWithAttributedString:attachmentString]; NSAttributedString *myText = [[NSMutableAttributedString alloc] initWithString:text]; [myString appendAttributedString:myText];
ReVerse le
153

Voici la façon d'intégrer l'icône dans UILabel.

Également pour aligner l'icône, utilisez la pièce jointe.


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

Version 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;

entrez la description de l'image ici

entrez la description de l'image ici

Tarun Seera
la source
22
Votez pour attachment.bounds
Peter Zhao
3
Excellent appel à l'utilisation de attachment.bounds. C'est exactement ce que je cherchais.
Geoherna
2
En fait, l'imageOffsetY peut être calculé au lieu d'utiliser une valeur fixe de -5,0. let imageOffsetY: CGFloat = - (imageAttachment.image! .size.height - self.mobileLabel.font.pointSize) / 2.0;
JonSlowCN
Remarque: il ralentit le temps de compilation
Jack
Je peux le faire sur un 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
la source
23

Votre image de référence ressemble à un bouton. Essayez (peut également être fait dans Interface Builder):

entrez la description de l'image ici

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];
Un gars
la source
Bien expliqué, j'aime le fait que vous ayez pris le temps de fournir une réf. Cela m'a beaucoup aidé! Merci
Shinnyx
Cela a aidé à transformer mon icône de trophée en bouton. Merci beaucoup!
Harish le
23

Version 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

Extension 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
la source
17

J'ai fait une implémentation de cette fonctionnalité en swift ici: https://github.com/anatoliyv/SMIconLabel

Le code est aussi simple que possible:

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)

Voici à quoi ça ressemble:

Image SMIconLabel

anatoliy_v
la source
13

UIlabelExtension Swift 4 pour ajouter une image à l'étiquette en référence aux réponses ci-dessus

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
  }
}
Agent Smith
la source
NSAttributedString(string: " " + text, attributes: [.font: self.font])
Farzad le
@grizzly est-ce pour créer un espace entre l'icône et le texte?
Agent Smith
Oui. est un autre moyen pour l'espace entre l'icône et le texte?
Farzad le
4

Version 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
la source
3

Essayez de faire glisser un UIViewsur l'écran dans IB. De là, vous pouvez faire glisser un UIImageViewet UILabeldans la vue que vous venez de créer. Définissez l'image du UIImageViewdans l'inspecteur des propriétés comme image de puce personnalisée (que vous devrez ajouter à votre projet en le faisant glisser dans le volet de navigation) et vous pouvez écrire du texte dans l'étiquette.

nanothread59
la source
2

essayez de cette façon ...

  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
la source
Cela vous est-il utile?
user1673099
cette approche manque le décalage du texte pour l'image (le texte se trouve derrière l'image)
brigadir
2

Swift 5 Easy Way Copiez et modifiez ce que vous voulez

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

entrez la description de l'image ici

Shakeel Ahmed
la source
1

Vous pouvez utiliser un UITextField avec la propriété leftView , puis définir la enabledpropriété surNO

Ou utilisez un UIButton etsetImage:forControlState

liamnichols
la source
1

Dans Swift 2.0,

Ma solution au problème est une combinaison de quelques réponses à cette question. Le problème que j'ai rencontré dans la réponse de @ Phil était que je ne pouvais pas changer la position de l'icône, et elle apparaissait toujours dans le coin droit. Et la seule réponse de @anatoliy_v, je n'ai pas pu redimensionner la taille de l'icône que je souhaite ajouter à la chaîne.

Pour que cela fonctionne pour moi, j'ai d'abord fait un pod 'SMIconLabel', puis créé cette fonction:

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
    }

Cette solution vous aidera non seulement à placer l'image, mais vous permettra également d'apporter les modifications nécessaires à la taille de l'icône et à d'autres attributs.

Merci.

Fennec
la source
1

Extension de Swift 3 UILabel

Conseil: si vous avez besoin d'un espace entre l'image et le texte, utilisez simplement un espace ou deux avant le labelText.

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
la source
1
Je l'ai utilisé et cela a parfaitement fonctionné. Les autres ci-dessus ont en fait retourné l'image à la fin de la chaîne.
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
} 

Vous pouvez utiliser cette fonction pour ajouter des images ou de petites icônes à l'étiquette

Ayush Dixit
la source
Call this in viewdidload ()
Ayush Dixit
let emojisCollection = [UIImage (named: "ic_place"), UIImage (named: "ic_group"), UIImage (named: "ic_analytics")] lbl1.attributedText = atributedLabel (str: "Howath, Dublin", img: emojisCollection [0 ]!) lbl2.attributedText = atributedLabel (str: "Difficulté: 18+", img: emojisCollection [2]!) lbl3.attributedText = atributedLabel (str: "Taille maximale du groupe: 10", img: emojisCollection [1]!)
Ayush Dixit
vous pouvez modifier votre réponse originale pour inclure ces commentaires ci-dessus.
Moondra
0

vous devez créer un objet personnalisé où vous avez utilisé un UIViewet à l'intérieur vous mettez un UIImageViewet unUILabel

Mirko Catalano
la source