Jak osadzić małą ikonę w UILabel


153

Muszę osadzić małe ikony (rodzaj niestandardowych pocisków) na moim UILabelw iOS7. Jak mogę to zrobić w projektancie interfejsu? A przynajmniej w kodzie?

W Androidzie są leftDrawablei rightDrawabledla etykiet, ale jak to się robi w iOS? Próbka w systemie Android:

próbka Androida


Nie jestem zaznajomiony z Androidem. Czy możesz opublikować jakiś obraz w celach informacyjnych?
user1673099

2
utwórz mały widok
obrazu

Odpowiedzi:


292

Możesz to zrobić za pomocą załączników tekstowych iOS 7 , które są częścią TextKit. Przykładowy kod:

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;

A co z iOS6? Czy masz jakieś sugestie?? Dzięki
Steven Jiang

1
@StevenJiang: Będziesz musiał po prostu dodać UIImageViewdo swojej etykiety
Scott Berrevoets

1
Niestety powoduje to umieszczenie ikony po tekście. Jest jakaś szansa, że ​​możemy przenieść to przed tekstem, ponieważ nie mogę znaleźć sposobu ?!
cofnij

4
@reVerse Zamiast dołączać obraz (ciąg załącznika) do ciągu tekstowego, możesz spróbować zrobić to na odwrót, dodając ciąg tekstowy do ciągu załącznika.
Scott Berrevoets

11
Próbowałem już tego wczoraj. Wydaje się, że coś przeoczyłem, ponieważ teraz działa. Dzięki. Na wszelki wypadek dla wszystkich, którzy próbują osiągnąć to samo (ponieważ jest nieco inny): NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment]; NSMutableAttributedString *myString = [[NSMutableAttributedString alloc] initWithAttributedString:attachmentString]; NSAttributedString *myText = [[NSMutableAttributedString alloc] initWithString:text]; [myString appendAttributedString:myText];
odwróć

153

Oto sposób na osadzenie ikony w UILabel.

Aby wyrównać ikonę, użyj attach.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

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

wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj


22
Głosuj na przywiązanie.bounds
Peter Zhao

3
Świetne wezwanie do korzystania z attach.bounds. Właśnie tego szukałem.
Geoherna

2
W rzeczywistości imageOffsetY można obliczyć zamiast używać stałej wartości -5,0. let imageOffsetY: CGFloat = - (imageAttachment.image! .size.height - self.mobileLabel.font.pointSize) / 2.0;
JonSlowCN

Uwaga: spowalnia to czas kompilacji
Jack

Mogę to zrobić na 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

23

Twój obraz referencyjny wygląda jak przycisk. Spróbuj (można to również zrobić w Interface Builder):

wprowadź opis obrazu tutaj

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

Dobrze wyjaśnione, podoba mi się fakt, że poświęciłeś czas na podanie referencji. Bardzo mi to pomogło! Dzięki
Shinnyx,

Pomogło to umieścić ikonę trofeum w przycisku. Wielkie dzięki!
Harish

23

Wersja 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

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

17

Wprowadziłem tę funkcję szybko tutaj: https://github.com/anatoliyv/SMIconLabel

Kod jest tak prosty, jak to tylko możliwe:

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)

Oto jak to wygląda:

Obraz SMIconLabel


13

UIlabelRozszerzenie Swift 4, aby dodać obraz do etykiety w odniesieniu do powyższych odpowiedzi

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

NSAttributedString(string: " " + text, attributes: [.font: self.font])
Farzad,

@grizzly służy do tworzenia odstępu między ikoną a tekstem?
Agent Smith

tak. czy jest inny sposób na odstęp między ikoną a tekstem?
Farzad,

4

Wersja 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

3

Spróbuj przeciągnąć UIViewna ekran w IB. Stamtąd możesz przeciągnąć UIImageViewi UILabeldo właśnie utworzonego widoku. Ustaw obraz UIImageVieww inspektorze właściwości jako niestandardowy obraz punktora (który będziesz musiał dodać do swojego projektu, przeciągając go do panelu nawigacji) i możesz wpisać tekst na etykiecie.


2

spróbuj w ten sposób ...

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

Czy to ci pomaga?
user1673099

to podejście pomija przesunięcie tekstu dla obrazu (tekst leży za obrazem)
brigadir

2

Swift 5 Easy Way Po prostu kopiuj Wklej i zmień to, co chcesz

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

wprowadź opis obrazu tutaj



1

W Swift 2.0,

Moje rozwiązanie problemu to połączenie kilku odpowiedzi na to pytanie. Problem z odpowiedzią @ Phila polegał na tym, że nie mogłem zmienić pozycji ikony i zawsze pojawiała się ona w prawym rogu. I jedyna odpowiedź od @anatoliy_v, nie mogłem zmienić rozmiaru ikony, którą chcę dołączyć do ciągu.

Aby to zadziałało, najpierw zrobiłem, pod 'SMIconLabel'a następnie utworzyłem tę funkcję:

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
    }

To rozwiązanie nie tylko pomoże Ci umieścić obraz, ale także pozwoli na wprowadzenie niezbędnych zmian w rozmiarze ikony i innych atrybutach.

Dziękuję Ci.


1

Rozszerzenie Swift 3 UILabel

Wskazówka: jeśli potrzebujesz spacji między obrazem a tekstem, po prostu użyj spacji lub dwóch przed etykietą 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
Użyłem tego i działało idealnie. Pozostałe powyżej faktycznie przerzuciły obraz na koniec struny.
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
} 

Możesz użyć tej funkcji, aby dodać obrazy lub małe ikony do etykiety


Wywołaj to w viewdidload ()
Ayush Dixit

let emojisCollection = [UIImage (o nazwie: "ic_place"), UIImage (o nazwie: "ic_group"), UIImage (o nazwie: "ic_analytics")] lbl1.attributedText = atributedLabel (str: "Howath, Dublin", img: emojisCollection [0 ]!) lbl2.attributedText = atributedLabel (str: "Trudność: 18+", img: emojisCollection [2]!) lbl3.attributedText = atributedLabel (str: "Maksymalna wielkość grupy: 10", img: emojisCollection [1]!)
Ayush Dixit

możesz edytować swoją oryginalną odpowiedź, aby uwzględnić te komentarze powyżej.
Moondra

0

musisz stworzyć niestandardowy obiekt, w którym użyłeś a, UIViewa wewnątrz umieściłeś a UIImageViewi aUILabel

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.