How to embed small icon in UILabel

IosObjective CCocoa TouchIos7Textkit

Ios Problem Overview


I need to embed small icons ( sort of custom bullets ) to my UILabel in iOS7. How can I do this in interface designer? Or at least in code?

In Android there are leftDrawable and rightDrawable for labels, but how it is done in iOS? Sample in android :

android sample

Ios Solutions


Solution 1 - Ios

You can do this with iOS 7's text attachments, which are part of TextKit. Some sample 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;

Solution 2 - Ios

Here is the way to embed icon in UILabel.

Also to Align the Icon 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

Objective-C Version

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;

enter image description here

enter image description here

Solution 3 - Ios

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

Solution 4 - Ios

Swift 3 version

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

UILabel Extension

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

Solution 5 - Ios

Your reference image looks like a button. Try (can also be done in Interface Builder):

enter image description here

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

Solution 6 - Ios

I've made an implementation of this feature in swift here: https://github.com/anatoliyv/SMIconLabel

Code is as simple as it's 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)

Here is how it looks:

SMIconLabel image

Solution 7 - Ios

Swift 4 UIlabel Extension to add Image to Label with reference to above answers

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

Solution 8 - Ios

Swift 5 Easy Way Just CopyPaste and change what you want

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

enter image description here

Solution 9 - Ios

In Swift 5, By using UILabel extensions to embed icon in leading as well as trailing side of the text as follows:-

extension UILabel {
    
    func addTrailing(image: UIImage, text:String) {
        let attachment = NSTextAttachment()
        attachment.image = image

        let attachmentString = NSAttributedString(attachment: attachment)
        let string = NSMutableAttributedString(string: text, attributes: [:])

        string.append(attachmentString)
        self.attributedText = string
    }
    
    func addLeading(image: UIImage, text:String) {
        let attachment = NSTextAttachment()
        attachment.image = image

        let attachmentString = NSAttributedString(attachment: attachment)
        let mutableAttributedString = NSMutableAttributedString()
        mutableAttributedString.append(attachmentString)
        
        let string = NSMutableAttributedString(string: text, attributes: [:])
        mutableAttributedString.append(string)
        self.attributedText = mutableAttributedString
    }
}

To use above mentioned code in your desired label as:-

Image in right of text then:-

statusLabel.addTrailing(image: UIImage(named: "rightTick") ?? UIImage(), text: " Verified ")

Image in left of text then:-

statusLabel.addLeading(image: UIImage(named: "rightTick") ?? UIImage(), text: " Verified ")

Output:-

enter image description here

enter image description here

Solution 10 - Ios

try this way...

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

Solution 11 - Ios

Try dragging a UIView onto the screen in IB. From there you can drag a UIImageView and UILabel into the view you just created. Set the image of the UIImageView in the properties inspector as the custom bullet image (which you will have to add to your project by dragging it into the navigation pane) and you can write some text in the label.

Solution 12 - Ios

Swift 2.0 version:

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

Solution 13 - Ios

You can extent UILabe pass the flag for the image add-in Leading or Trailing also set imageBounds if needed.

Swift 5+

extension UILabel {
    func add(image: UIImage, text: String, isLeading: Bool = true, imageBounds: CGRect = CGRect(x: 0, y: 0, width: 16, height: 12)) {
        let imageAttachment = NSTextAttachment()
        imageAttachment.bounds = imageBounds
        
        imageAttachment.image = image
        
        let attachmentString = NSAttributedString(attachment: imageAttachment)
        let string = NSMutableAttributedString(string: text)
        
        let mutableAttributedString = NSMutableAttributedString()
        
        if isLeading {
            mutableAttributedString.append(attachmentString)
            mutableAttributedString.append(string)
            attributedText = mutableAttributedString
        } else {
            string.append(attachmentString)
            attributedText = string
        }
    }
    }

Solution 14 - Ios

For somebody who wants to have an icon on the right end of their label, not necessarily immediately after the text, you can use this technique based on the idea in this answer: https://stackoverflow.com/a/19318843/826946 (Note there are some constants here you will probably want to adjust, but the general idea should be clear). This will not work if your label is being sized using its implicit size, only if you have some other constraint on the width that you are confident will leave room for your icon.

    let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
    imgView.image = UIImage(named: "arrow")
    myLabel.addSubview(imgView)
    imgView.translatesAutoresizingMaskIntoConstraints = false
    imgView.centerYAnchor.constraint(equalTo: myLabel.centerYAnchor, constant: 0).isActive = true
    imgView.rightAnchor.constraint(equalTo: myLabel.rightAnchor, constant: -20).isActive = true

Solution 15 - Ios

you have to make a custom object where you used a UIView and inside you put a UIImageView and a UILabel

Solution 16 - Ios

You could use a UITextField with the leftView property and then set the enabled property to NO

Or use a UIButton and setImage:forControlState

Solution 17 - Ios

 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
} 

You can use this function to add images or small icons to the label

Solution 18 - Ios

In Swift 2.0,

My solution to the problem is a combination of a couple of answers on this question. The problem I faced in @Phil's answer was that I couldn't change the position of the icon, and it always appeared in right the corner. And the one answer from @anatoliy_v, I couldn't resize the icon size I want to append to the string.

To make it work for me, I first did a pod 'SMIconLabel' and then created this function:

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
    }

This solution will not only help you place the image but will also allow you to make necessary changes to the icon size and other attributes.

Thank You.

Solution 19 - Ios

Swift 3 UILabel extention

Tip: If you need some space between the image and the text just use a space or two before the 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
    }
}

Solution 20 - Ios

If you don't absolutely need a label (and there may be some situations where you do), you can use a view hierarchy with constraints to create a UIView that can be placed where a label would go. And, of course the image and label text of the composite view can be updated dynamically.

func configureTitleLabelWithIcon(text: String, parent: UIView) {

    let iconAndLabel = UIView()
    let label = UILabel()
    let icon  = UIImageView(image:UIImage(systemName: "globe"))

    label.text = text
    label.textColor = UIColor.secondaryLabel
    
    label.translatesAutoresizingMaskIntoConstraints = false
    ico .translatesAutoresizingMaskIntoConstraints = false
    iconAndLabel.translatesAutoresizingMaskIntoConstraints = false

    iconAndLabel.addSubview(icon)
    iconAndLabel.addSubview(label)

    icon.widthAnchor.constraint(  equalToConstant: 14).isActive = true
    icon.heightAnchor.constraint( equalToConstant: 14).isActive = true

    iconAndLabel.widthAnchor.constraint(  equalToConstant: 200).isActive = true
    iconAndLabel.heightAnchor.constraint( equalToConstant: 22).isActive = true

    icon.leadingAnchor.constraint(equalTo:   iconAndLabel.leadingAnchor).isActive = true
    icon.trailingAnchor.constraint(equalTo:  label.leadingAnchor, constant: -7).isActive = true
    label.trailingAnchor.constraint(equalTo: iconAndLabel.trailingAnchor).isActive = true
    icon.centerYAnchor.constraint(equalTo:   iconAndLabel.centerYAnchor).isActive = true
    view.addSubview(iconAndLabel)

    label.centerXAnchor.constraint(equalTo: parent, constant: 10).isActive = true
    label.bottomAnchor.constraint(equalTo:  parent, constant: -75).isActive = true
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAVEbrahimiView Question on Stackoverflow
Solution 1 - IosScott BerrevoetsView Answer on Stackoverflow
Solution 2 - IosTarun SeeraView Answer on Stackoverflow
Solution 3 - IosAndré Dos SantosView Answer on Stackoverflow
Solution 4 - IosRajeshKumar RView Answer on Stackoverflow
Solution 5 - IosSomeGuyView Answer on Stackoverflow
Solution 6 - Iosanatoliy_vView Answer on Stackoverflow
Solution 7 - IosAgent SmithView Answer on Stackoverflow
Solution 8 - IosShakeel AhmedView Answer on Stackoverflow
Solution 9 - IosAshutosh MishraView Answer on Stackoverflow
Solution 10 - Iosuser1673099View Answer on Stackoverflow
Solution 11 - IosnanothreadView Answer on Stackoverflow
Solution 12 - IosPhilView Answer on Stackoverflow
Solution 13 - IosBinoy joseView Answer on Stackoverflow
Solution 14 - IosAndy WeinsteinView Answer on Stackoverflow
Solution 15 - IosMirko CatalanoView Answer on Stackoverflow
Solution 16 - IosliamnicholsView Answer on Stackoverflow
Solution 17 - IosAyush DixitView Answer on Stackoverflow
Solution 18 - Iostush4rView Answer on Stackoverflow
Solution 19 - IosGary ManstedView Answer on Stackoverflow
Solution 20 - IosclearlightView Answer on Stackoverflow