Reputation: 121
Hi I wanna add image round dot to some UILabel in my app.
I have code for adding the image. But I don't understand how I could put the image on the start of the UILabel rather than in the end of the label.
Any suggestion on this? Below is the code I use for it: What should I add to place image on start of UILabel? I thought imageBehindText :false would fix it but it didn't.
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.20) // rounded dot should be smaller than font
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
}
}
Upvotes: 3
Views: 2485
Reputation: 3867
lazy var attachment: NSTextAttachment = {
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "")
return attachment
}()
it will work for both remote and local image
if let imageUrl = imageUrl, imageUrl.count > 0, let url = URL(string: imageUrl) {
let imageAttachmentString = NSAttributedString(attachment: attachment)
attachment.bounds = CGRect(x: 0, y: (titleLabel.font.capHeight - 16) / 2, width: 16, height: 16)
BaseAPI().downloadImage(with: url, placeHolder: "") { [weak self] image, error, success, url in
if let image = image, let self = self {
DispatchQueue.main.async {
let finalString = NSMutableAttributedString(string: "")
let titleString = NSMutableAttributedString(string: self.title)
let space = NSMutableAttributedString(string: " ")
let imageAttachment = self.attachment
imageAttachment.image = image
finalString.append(imageAttachmentString)
finalString.append(space)
finalString.append(titleString)
self.titleLabel.attributedText = finalString
}
}
}
} else { titleLabel.text = title }
Upvotes: 0
Reputation: 121
I got it to work. The problem was that I was setting the text in the storyboard(.xib). So this extension didn't change the image to the front even if the bool-val were false.
Simply set the text from the function-call and the 'false' value will trigger the image to be set in the start of the uilabel.
Example1 (what I did wrong):
// This is what I tried first!
label.addTextWithImage(text: "",
image: UIImage(named: embededIcon)!,
imageBehindText: false, // note! This is false.
keepPreviousText: true) // this was the problem!
Example2 (what got it to work!):
label.addTextWithImage(text: "putYourLabelTextHere!", // You have to put text here, even if it's already in storyboard.
image: UIImage(named: embededIcon)!,
imageBehindText: false,
keepPreviousText: false) // false, so the image will be set before text!
Upvotes: 2