如何在UILabel中嵌入小图标

191

我需要将小图标(类似自定义符号)嵌入到我的 iOS7 的 UILabel 中。 在界面设计中,我该如何实现?或者至少在代码中怎么做呢?

在 Android 中,标签有左侧和右侧的 drawable 属性,但在 iOS 中该如何实现呢? Android 示例:

android sample


我不熟悉Android,你能发布一些图片作为参考吗? - user1673099
2
创建一个小的ImageView,并将其作为子视图添加到标签对象中。 - Saurabh Passolia
21个回答

3

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

3

Swift 5+

如果您想保持图像的比例,并始终将图像与文本居中对齐,则这是我的解决方案:

extension UILabel {
    var mutableAttributedString: NSMutableAttributedString? {
        let attributedString: NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            guard let labelText = self.text else { return nil }
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.alignment = self.textAlignment
            attributedString = NSMutableAttributedString(string: labelText)
            attributedString.addAttribute(NSAttributedString.Key.paragraphStyle,
                                          value: paragraphStyle,
                                          range: NSRange(location: 0, length: attributedString.length))
        }
        return attributedString
    }

    func addImage(_ image: UIImage, toEndWith height: CGFloat) {
        let fullAttributedString = mutableAttributedString
        let imageAttachment = NSTextAttachment()
        imageAttachment.image = image

        let yImage = (font.capHeight - height).rounded() / 2
        let ratio = image.size.width / image.size.height
        imageAttachment.bounds = CGRect(x: 0, y: yImage, width: ratio * height, height: height)
        
        let imageString = NSAttributedString(attachment: imageAttachment)
        fullAttributedString?.append(imageString)
        attributedText = fullAttributedString
    }
    
    func addImage(_ image: UIImage, toStartWith height: CGFloat) {
        let imageAttachment = NSTextAttachment()
        imageAttachment.image = image

        let yImage = (font.capHeight - height).rounded() / 2
        let ratio = image.size.width / image.size.height
        imageAttachment.bounds = CGRect(x: 0, y: yImage, width: ratio * height, height: height)
        
        let fullAttributed = NSMutableAttributedString(attachment: imageAttachment)
        if let rawAttributed = mutableAttributedString {
            fullAttributed.append(rawAttributed)
        }
        attributedText = fullAttributed
    }
}

以下是如何使用上述扩展的方法:

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
label.font = .systemFont(ofSize: 20)
let image = UIImage(systemName: "square.and.pencil")!
label.text = "Hi, "
label.addImage(image, toEndWith: 10)

以下是一些例子:

enter image description here

enter image description here

enter image description here

使用带属性的字符串:

let myString = "Hi, "
let myAttribute: [NSAttributedString.Key: UIColor] = [.foregroundColor: .blue]
let myAttrString = NSAttributedString(string: myString, attributes: myAttribute)
label.attributedText = myAttrString
label.addImage(image, toEndWith: 15)

enter image description here


2

对于想要在标签右端而不一定是文本后面立即显示图标的人,可以使用这个技巧,它基于这个答案中的思路:https://dev59.com/TmIk5IYBdhLWcg3wYtX7#19318843(请注意,这里有一些常量您可能需要调整,但总体思路应该很清楚)。如果您的标签使用其隐式大小进行调整,则此方法将无效,只有当您对宽度有其他约束并且确信会留出空间放置图标时才有效。

    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

2

尝试在IB中将UIView拖动到屏幕上。从那里,您可以将UIImageViewUILabel拖入您刚刚创建的视图中。在属性检查器中将UIImageView的图像设置为自定义符号图像(您需要通过将其拖入导航窗格中将其添加到项目中),然后在标签中编写一些文本。


2
您可以通过传递Leading或Trailing标志来扩展UILabe,也可以根据需要设置imageBounds。

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

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
} 

您可以使用此功能向标签添加图像或小图标。

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: " 难度:18+", img: emojisCollection[2]!) lbl3.attributedText = atributedLabel(str: " 最大团队人数:10", img: emojisCollection[1]!) - Ayush Dixit
请勿解释原文。 - Moondra

1

你需要创建一个自定义对象,在其中使用 UIView,并在其内部放置一个 UIImageView 和一个 UILabel


1

您可以使用带有UITextFieldleftView属性,然后将enabled属性设置为NO

或者使用UIButton并使用setImage:forControlState


0
在Swift 2.0中,
我对这个问题的解决方案是结合了这个问题上的几个答案。在@Phil的答案中,我遇到的问题是我无法更改图标的位置,它总是出现在右上角。而来自@anatoliy_v的一个答案,我无法调整要附加到字符串的图标大小。
为了让它对我起作用,我首先执行了pod 'SMIconLabel',然后创建了这个函数:
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
    }

这个解决方案不仅可以帮助您放置图像,还可以让您对图标大小和其他属性进行必要的更改。

谢谢。


0

Swift 3 UILabel扩展

提示:如果您需要在图像和文本之间添加一些空间,只需在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
    }
}

1
我使用了这个,它完美地工作了。上面的其他方法实际上将图像翻转到字符串的末尾。 - mondousage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接