Formater UILabel avec des puces?

89

Est-il possible de formater le textdans un UILabelpour afficher une puce ?

Si oui, comment puis-je le faire?

Rob
la source
@Hoque: UILabels ne traite pas leur texte comme du HTML.
Ben Zotto le
2
Voici une classe pour ça! codeload.github.com/eyalc/ECListView/zip/master
Hemang
20
Pourquoi est-ce fermé comme hors sujet? C'est une question légitime avec une réponse légitime.
len
2
Pourquoi diable est-ce marqué comme hors sujet par stackoverflow.com/users/237838/andrew-barber, c'est peut-être un doublon mais en aucun cas hors sujet ...
AppHandwerker
2
Touche de raccourciALT+8 = •
TheTiger

Réponses:

162

Peut-être utiliser le point de code Unicode pour le caractère de puce dans votre chaîne?

Objectif c

myLabel.text = @"\u2022 This is a list item!";

Swift 4

myLabel.text = "\u{2022} This is a list item!"
Chris Doble
la source
4
Pardonnez mon ignorance mais j'utilise tout le temps des UILabels et je me demande si vous pourriez indiquer un "par exemple".
daveMac
1
myLabel.numberOfLines = 0vous obtient une étiquette multiligne qui respectera les caractères de saut de ligne. En général, j'aime bien l'utiliser UITextFieldcar il est plus flexible. Par exemple, vous pouvez facilement détecter le caractère sur lequel un utilisateur a tapé lorsqu'il travaille avec a UITextField, je ne pense pas que vous puissiez le faire avec a UILabel. Les vues de texte ont également de nombreuses autres fonctionnalités intéressantes.
John Erck
7
Une autre façon est d'utiliseroption+8
atulkhatri
3
N'oubliez pas d'utiliser un «u» majuscule si vous utilisez des chaînes localisables: \ U2022
Nikolaj Nielsen
1
Swift est légèrement différent, "\ u {2022}"
anders le
80

il suffit d'ajouter " • "

Même moi, je cherchais quelque chose comme ça pour mon textView. Ce que j'ai fait, ajoutez simplement la chaîne ci-dessus avec ma chaîne et passez-la à mon textView, la même chose peut être faite pour labelsaussi.

J'ai répondu à cela pour le futur spectateur.

Zac24
la source
• A travaillé pour moi. J'ai eu * dans Xcode que je viens de copier / remplacer en utilisant • et cela a bien fonctionné pour mon étiquette J'ai remplacé "Label" par •
Brian
46

Voici une belle solution avec Swift

let label = UILabel()
label.frame = CGRect(x: 40, y: 100, width: 280, height: 600)
label.textColor = UIColor.lightGray
label.numberOfLines = 0

let arrayString = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
    "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
    "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
]

label.attributedText = add(stringList: arrayString, font: label.font, bullet: "")

self.view.addSubview(label)

Ajouter des attributs de puce

func add(stringList: [String],
         font: UIFont,
         bullet: String = "\u{2022}",
         indentation: CGFloat = 20,
         lineSpacing: CGFloat = 2,
         paragraphSpacing: CGFloat = 12,
         textColor: UIColor = .gray,
         bulletColor: UIColor = .red) -> NSAttributedString {

    let textAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: textColor]
    let bulletAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: bulletColor]

    let paragraphStyle = NSMutableParagraphStyle()
    let nonOptions = [NSTextTab.OptionKey: Any]()
    paragraphStyle.tabStops = [
        NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)]
    paragraphStyle.defaultTabInterval = indentation
    //paragraphStyle.firstLineHeadIndent = 0
    //paragraphStyle.headIndent = 20
    //paragraphStyle.tailIndent = 1
    paragraphStyle.lineSpacing = lineSpacing
    paragraphStyle.paragraphSpacing = paragraphSpacing
    paragraphStyle.headIndent = indentation

    let bulletList = NSMutableAttributedString()
    for string in stringList {
        let formattedString = "\(bullet)\t\(string)\n"
        let attributedString = NSMutableAttributedString(string: formattedString)

        attributedString.addAttributes(
            [NSAttributedStringKey.paragraphStyle : paragraphStyle],
            range: NSMakeRange(0, attributedString.length))

        attributedString.addAttributes(
            textAttributes,
            range: NSMakeRange(0, attributedString.length))

        let string:NSString = NSString(string: formattedString)
        let rangeForBullet:NSRange = string.range(of: bullet)
        attributedString.addAttributes(bulletAttributes, range: rangeForBullet)
        bulletList.append(attributedString)
    }

    return bulletList
}

Voici le résultat:

entrez la description de l'image ici

Krunal
la source
C'est une solution très élégante.
JeroenJK
9

Dans Swift 4, j'ai utilisé "•" avec une nouvelle ligne

 @IBOutlet weak var bulletLabel: UILabel!
 let arrayOfLines = ["Eat egg for protein","You should Eat Ghee","Wheat is with high fiber","Avoid to eat Fish "]
 for value in arrayOfLines {
     bulletLabel.text = bulletLabel.text!  + " • " + value + "\n"
  }

Production:

entrez la description de l'image ici

Jack
la source
9
pourquoi éviter le poisson
rd_
7

Dans Swift 3.1

lblItemName.text = "\u{2022} This is a list item!"
Daxesh Nagar
la source
3

Consultez ce lien, j'ai créé une vue personnalisée pour formater le texte avec des puces / autres symboles / image (en utilisant la propriété attributeText de UILabel) comme symbole d'élément de liste (Swift 3.0) https://github.com/akshaykumarboth/SymbolTextLabel-iOS- Rapide

 import UIKit

    class ViewController: UIViewController {

    @IBOutlet var symbolView: SymbolTextLabel!

    var testString = "Understanding the concept of sales"

    var bulletSymbol = "\u{2022}" 
    var fontsize: CGFloat= 18
    override func viewDidLoad() {

        super.viewDidLoad()
         //First way // Dynamically creating SymbolTextLabel object

        let symbolTextLabel = SymbolTextLabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))

        symbolTextLabel.setText(text: testString, symbolCode: bulletSymbol) //setting text and symbol of text item

        symbolTextLabel.setFontSize(textSize: fontsize) // setting font size

        //symbolTextLabel.setSpacing(spacing: 5) // setting space between symbol and text

        self.view.addSubview(symbolTextLabel) 
//second way // from storyboard or interface builder

     symbolView.setText(text: testString, symbolCode: bulletSymbol)
 //setting text and symbol of text item 

    symbolView.setFontSize(textSize: fontsize) // setting font size

        //symbolView.setSpacing(spacing: 5) // setting space between symbol and text

         } 
    }
Akshay Kumar les deux
la source
2

Si vous souhaitez également aligner le texte en retrait pour les puces, vous pouvez utiliser la méthode suivante qui génère un NSAttributedStringavec les propriétés d'indentation et d'espacement appropriées:

- (NSAttributedString *)attributedStringForBulletTexts:(NSArray *)stringList
                                              withFont:(UIFont *)font
                                          bulletString:(NSString *)bullet
                                           indentation:(CGFloat)indentation
                                           lineSpacing:(CGFloat)lineSpacing
                                      paragraphSpacing:(CGFloat)paragraphSpacing
                                             textColor:(UIColor *)textColor
                                           bulletColor:(UIColor *)bulletColor {

    NSDictionary *textAttributes = @{NSFontAttributeName: font,
                                 NSForegroundColorAttributeName: textColor};
    NSDictionary *bulletAttributes = @{NSFontAttributeName: font, NSForegroundColorAttributeName: bulletColor};

    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    paragraphStyle.tabStops = @[[[NSTextTab alloc] initWithTextAlignment: NSTextAlignmentLeft location:indentation options:@{}]];
    paragraphStyle.defaultTabInterval = indentation;
    paragraphStyle.lineSpacing = lineSpacing;
    paragraphStyle.paragraphSpacing = paragraphSpacing;
    paragraphStyle.headIndent = indentation;

    NSMutableAttributedString *bulletList = [NSMutableAttributedString new];

    for (NSString *string in stringList) {
        NSString *formattedString = [NSString stringWithFormat:@"%@\t%@\n", bullet, string];
        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:formattedString];
        if (string == stringList.lastObject) {
            paragraphStyle = [paragraphStyle mutableCopy];
            paragraphStyle.paragraphSpacing = 0;
        }
        [attributedString addAttributes:@{NSParagraphStyleAttributeName: paragraphStyle} range:NSMakeRange(0, attributedString.length)];
        [attributedString addAttributes:textAttributes range:NSMakeRange(0, attributedString.length)];

        NSRange rangeForBullet = [formattedString rangeOfString:bullet];
        [attributedString addAttributes:bulletAttributes range:rangeForBullet];
        [bulletList appendAttributedString:attributedString];
    }

    return bulletList;
}

Et vous pouvez utiliser cette méthode comme suit, en passant un NSArrayavec les textes et à condition que vous ayez déjà un UILabel:

NSArray *stringArray = @[@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                         @"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
                         @"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
                         @"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
                         ];

label.attributedText = [self attributedStringForBulletTexts:stringArray
                                                   withFont:label.font
                                               bulletString:@"•"
                                                indentation:15
                                                lineSpacing:2
                                           paragraphSpacing:10
                                                  textColor:UIColor.blackColor
                                                bulletColor:UIColor.grayColor];
Jonathan Cabrera
la source
1

Oui. Copiez et collez la puce suivante: le compilateur de Swift peut interpréter et afficher la puce comme vous le souhaitez dans Xcode, rien d'autre n'est nécessaire.

Réutilisation

extension String {
    static var bullet: String {
        return "• "
    }
}


print(String.bullet + "Buy apples")
let secondPoint: String = .bullet + "Buy oranges"
print(secondPoint)

production

 Buy apples
 Buy oranges

Tableau réutilisable

extension Array where Element == String {

    var bulletList: String {
        var po = ""
        for (index, item) in self.enumerated() {
            if index != 0 {
                po += "\n"
            }
            po += .bullet + item
        }
        return po
    }
}


print(["get apples", "get oranges", "get a bannana"].bulletList)

production

 get apples
 get oranges
 get a bannana
ScottyBlades
la source
1
Si vous votez contre. Au moins, ayez la courtoisie de dire pourquoi.
ScottyBlades
Je pense que la raison est que votre solution n'est pas optimale. Il est préférable d'utiliser le point de code Unicode.
Robert J. Clegg
Merci pour la réponse réfléchie. Pourquoi le point Unicode est-il meilleur?
ScottyBlades
Parce que, si le développeur avait besoin de le faire plusieurs fois, sur différents écrans ou projets (pas dans la même période), il en profiterait davantage, en sachant quelle est la valeur du point de code. Ainsi, pas besoin d'aller et d'affiner la réponse ci-dessus ou un endroit similaire, pour la copier. Eh bien, c'est ce que je pense de toute façon.
Robert J. Clegg
1
@ RobertJ.Clegg Je viens de mettre à jour ma réponse pour fournir une option réutilisable. Pouvez-vous me donner un exemple de cas où une chaîne de points de code rend la puce plus réutilisable qu'une chaîne de points de puce directe?
ScottyBlades
0

Si vous recherchez du texte textview avec des puces comme moi, voici la réponse. Au fait, cela ne fonctionne que pour le texte statique.

   Better experience - Refer a friend and How to Play \n Tournaments performance improvement\n UI/UX Improvements\n Critical bug fixes

J'ai attribué le texte ci-dessus à textview. Cela a fonctionné comme prévu pour moi.

Narasimha Nallamsetty
la source
0

Voici la solution de @krunal refactorisée en NSAttributedStringextension Swift 5 :

import UIKit

public extension NSAttributedString {
    static func makeBulletList(from strings: [String],
                               bulletCharacter: String = "\u{2022}",
                               bulletAttributes: [NSAttributedString.Key: Any] = [:],
                               textAttributes: [NSAttributedString.Key: Any] = [:],
                               indentation: CGFloat = 20,
                               lineSpacing: CGFloat = 1,
                               paragraphSpacing: CGFloat = 10) -> NSAttributedString
    {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.defaultTabInterval = indentation
        paragraphStyle.tabStops = [
            NSTextTab(textAlignment: .left, location: indentation)
        ]
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.paragraphSpacing = paragraphSpacing
        paragraphStyle.headIndent = indentation

        let bulletList = NSMutableAttributedString()

        for string in strings {
            let bulletItem = "\(bulletCharacter)\t\(string)\n"

            var attributes = textAttributes
            attributes[.paragraphStyle] = paragraphStyle

            let attributedString = NSMutableAttributedString(
                string: bulletItem, attributes: attributes
            )

            if !bulletAttributes.isEmpty {
                let bulletRange = (bulletItem as NSString).range(of: bulletCharacter)
                attributedString.addAttributes(bulletAttributes, range: bulletRange)
            }

            bulletList.append(attributedString)
        }

        if bulletList.string.hasSuffix("\n") {
            bulletList.deleteCharacters(
                in: NSRange(location: bulletList.length - 1, length: 1)
            )
        }

        return bulletList
    }
}
Tadija
la source