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

AVEbrahimi
źródło
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;
Scott Berrevoets
źródło
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

Tarun Seera
źródło
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
André Dos Santos
źródło
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];
Jakiś facet
źródło
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
    }
}
RajeshKumar R.
źródło
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

anatoliy_v
źródło
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
  }
}
Agent Smith
źródło
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
Phil
źródło
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.

nanothread59
źródło
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];
user1673099
źródło
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

Shakeel Ahmed
źródło
1

Możesz użyć UITextField z właściwością leftView, a następnie ustawić enabledwłaściwość naNO

Lub użyj UIButton isetImage:forControlState

liamnichole
źródło
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.

Fennec
źródło
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
    }
}
Gary Mansted
źródło
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

Ayush Dixit
źródło
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

Mirko Catalano
źródło