Format UILabel with bullet points?
Asked Answered
P

12

108

Is it possible to format the text in a UILabel to show a bullet point?

If so, How can I do it?

Presumptive answered 4/4, 2011 at 1:52 Comment(6)
@Hoque: UILabels don't treat their text as HTML.Bite
Here's a class for this! codeload.github.com/eyalc/ECListView/zip/masterNadenenader
Why is this closed as off-topic? This is a legitimate question with a legitimate answer.Selfregard
Why on earth is this marked as off topic by stackoverflow.com/users/237838/andrew-barber its possibly a duplicate but by no means off topic...Psychomancy
Shortcut key ALT+8 = •Disoperation
Possible duplicate of NSAttributedString inserting a bullet point?Pushed
L
191

Perhaps use the Unicode code point for the bullet character in your string?

Objective-c

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

Swift 4

myLabel.text = "\u{2022} This is a list item!"
Lyse answered 4/4, 2011 at 1:54 Comment(10)
I would also use a UITextField for bullets because a UILabel is going to be much more difficult.Boyfriend
@daveMac UILabels are typically the easiest to use with one line of text. When you get to longer/bigger blocks of text (the way bullets are formatted), a UITextField will likely be easier to work withBoyfriend
Forgive my ignorance but I use UILabels all of the time and I wonder if you could point out a "for instance".T
myLabel.numberOfLines = 0 gets you a multi-line label that will respect line break characters. In general though I like to use UITextField because it's more flexible. For example, you can easily detect which character a user tapped on when working with a UITextField, I don't think you can do that with a UILabel. Text views also have many other neat features.Libation
For more bullet options check Xcode > Edit > Special Characters... or use the shortcut control command space.Libation
Another way is to use option+8Bloomers
Visit this link for more symbol code alanwood.net/unicode/geometric_shapes.htmlLonilonier
Remember to use capital 'u' if you use localizable strings: \U2022Humic
Swift is slightly different, "\u{2022}"Dhumma
Alt + asterisk = • ... But all are talking about how to show bullet character, what I actually need to format the text with bullets.Disoperation
D
97

just add " • "

Even i was looking for something like this for my textView. What i did, just append above string with my string and pass it to my textView, same can be done for labels also.

I answered this for future Viewer.

Decomposer answered 23/7, 2013 at 14:59 Comment(1)
• Worked for me. I had * in Xcode I just copy/replaced using • and it worked fine for my Label I replaced "Label" with •Lianneliao
G
81

Here is nice solution with 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)

Add bullet attributes

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
}

Here is result:

enter image description here

Gokey answered 23/10, 2017 at 14:23 Comment(1)
This is a very elegant solution.Copyright
M
11

In Swift 4 i have used " • " with new Line

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

Output:

enter image description here

Morpheus answered 8/11, 2017 at 12:9 Comment(1)
why to avoid fishHypnotist
N
8

In swift 3.1

lblItemName.text = "\u{2022} This is a list item!"
Neuropathy answered 20/6, 2017 at 13:42 Comment(0)
I
7

Yes. Copy and paste the following bullet: Swift's compiler can interpret and display the bullet as desired within Xcode, nothing else needed.

Reuse

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


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

output

• Buy apples
• Buy oranges

Reusable array

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)

output

• get apples
• get oranges
• get a bannana
Insinuating answered 28/11, 2018 at 2:4 Comment(5)
If you downvote. At least have the courtesy to say why.Insinuating
I think the reason is due to your solution not being optimal. Using the unicode code point is best.Apocryphal
Thank you for the thoughtful response. Why is the Unicode point better?Insinuating
Because, if the developer needed to do this multiple times, across different screens or projects (Not in the same time period) it would benefit them more, by knowing what the code point value is. Thus, not needing to go and fine the above answer or similar place,to copy it from. Well, that's my thoughts on it anyway.Apocryphal
@RobertJ.Clegg I just updated my answer to provide a reusable option. Can you give me an example of when a code point string make the bullet point more reusable than a direct bullet point string?Insinuating
P
4

If you want to align the text indenting for the bullet points as well, you can use the following method that builds a NSAttributedString with the proper indentation and spacing properties:

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

And you can use that method as follows, by passing an NSArray with the texts and providing you already have a 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];
Pushed answered 24/7, 2018 at 15:57 Comment(1)
There is a small issue with this code, it will add an extra line break at the end. So you need to add a conditional, if it's the last line, don't add a newline. Like: NSString *lineWrap = string == stringList.lastObject ? @"" : @"\n"; NSString *formattedString = [NSString stringWithFormat:@"%@\t%@%@", bullet, string, lineWrap];Arequipa
F
3

Check out this link, I made a Custom view to format text with bullet points/ other symbols/ image(using attributeText property of UILabel) as list item symbol (Swift 3.0) https://github.com/akshaykumarboth/SymbolTextLabel-iOS-Swift

 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

         } 
    }
Fuddle answered 29/8, 2017 at 19:20 Comment(0)
S
2

Here's the solution from @krunal refactored into Swift 5 NSAttributedString extension:

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
    }
}
Skylar answered 21/4, 2020 at 10:52 Comment(0)
L
0

The solution for me is using a extension on uilabel

extension UILabel{
func setBulletAttributes(bullet:String , text:String){
    var attributes = [NSAttributedString.Key: Any]()
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.headIndent = (bullet as NSString).size(withAttributes: attributes).width
    attributes[.paragraphStyle] = paragraphStyle
    self.attributedText = NSAttributedString(string: text, attributes: attributes)
}

And call it:

var bullet = "* "
self.label.setBulletAttributes(bullet:bullet, text: bullet + "Test *****")
Luncheon answered 20/12, 2022 at 13:5 Comment(0)
D
-1

If anyone looking for textview text with bullet points like me, below is the answer. By the way it works only for static text.

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

I have assigned above text to textview. It worked as intended for me.

Deed answered 16/4, 2020 at 18:20 Comment(0)
E
-1

Here I have added an alert view controller with bullet points, Hope this helps.

*** Note: This is for only UIAlertViewController

  func showBulletPointsAlert(title:String,subTitles:[String],getCompleted: @escaping((_ selected: Int) -> ())) {
        let alertController = UIAlertController(title: "\(title)\n", message: nil, preferredStyle: .alert)
        let value = convertToList(subTitles: subTitles, font: .boldSystemFont(ofSize: 14))
        alertController.setValue(value, forKey: "attributedMessage")

        let okAction = UIAlertAction(title: "Continue", style: .default, handler: { _ in
            getCompleted(0)
        })
        alertController.addAction(okAction)

        if let rootViewController = UIApplication.shared.windows.first?.rootViewController {
            rootViewController.present(alertController, animated: true, completion: nil)
        }
    }
    
    func convertToList(subTitles: [String],
             font: UIFont,
             bullet: String = "\u{2022}",
             indentation: CGFloat = 20,
             lineSpacing: CGFloat = 2,
             paragraphSpacing: CGFloat = 12,
             textColor: UIColor = .gray,
                       bulletColor: UIColor = ThemeManager.shared.mainTextColor) -> NSAttributedString {

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

        let paragraphStyle = NSMutableParagraphStyle()
        let nonOptions = [NSTextTab.OptionKey: Any]()
        paragraphStyle.tabStops = [
            NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)]
        paragraphStyle.defaultTabInterval = indentation
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.paragraphSpacing = paragraphSpacing
        paragraphStyle.headIndent = indentation
        paragraphStyle.lineBreakMode = .byCharWrapping

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

            attributedString.addAttributes(
                [NSAttributedString.Key.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
    }
   
Edie answered 23/6, 2023 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.