In my iOS app I'm using NSAttributedString to generate a list of bullets. Unfortunately I'm struggling with making the bullets look presentable. My first attempt was to use regular text and a unicode character for the bullets, basically using a string like this:
var attributedString = NSMutableAttributedString(
string: "Here is a list of bullets and a paragraph introducing them, note that this paragraph spans multiple lines\n" +
"• This is the first bullet\n" +
"• Here is a second bullet\n" +
"• And here is a third bullet with a lot of text such that it overflows to the next line"
)
The result was this:
I like how the bullets look, but the overflowing text in the last bullet should be aligned with the line before and I couldn't figure out how to achieve that with plain text (without applying the same alignment to the paragraph above).
My 2nd attempt was to use html in NSAttributedString via NSHTMLTextDocumentType, and use <ul>
and <li>
elements to generate the bullets.
let content = "Here is a list of bullets and a paragraph introducing them, note that this paragraph spans multiple lines" +
"<ul>" +
"<li>This is the first bullet</li>" +
"<li>Here is a second bullet</li>" +
"<li>And here is a third bullet with a lot of text such that it overflows to the next line</li>" +
"</ul>"
var attributedString = try! NSMutableAttributedString(
data: content,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil
)
That fixed the first issue but introduced a new one:
The bullets are now spaced too far (both from the left edge and the text on the right). I tried to use the typical html/css tricks to fix the alignment (<li style="text-indent: -10px;">
) but those styles seem to be ignored by NSAttributedString.
I tried to remedy this with an additional NSMutableParagraphStyle but it seems to do more harm than good. Here is what I tried:
var paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.firstLineHeadIndent = 0
paragraphStyle.headIndent = 20
attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: attributedStringRange)
And here is what I got:
As you can see, it only made things worse, here are my issues with it:
All I really want is for my bullet spacing to look similar to the first screenshot while the overflow indent for second line to look like the second without having to hardcode exact pixel positions. Could you guys help me out?
Thanks
You can use . parentOfUl{ text-align:center;} and then ul{ display:inline-block; }, and at last li{ text-align:center; }.
An NSAttributedString object manages character strings and associated sets of attributes (for example, font and kerning) that apply to individual characters or ranges of characters in the string. An association of characters and their attributes is called an attributed string.
Use <table>
instead of <ul><li>
to handle the bullet alignment.
Styles like ul{margin:0;padding:0}
or li{margin-left: 0;}
will be ignored.
Example:
let html = "<table>" +
"<tr><td valign=\"top\" style=\"padding-right:16px\">•</td><td valign=\"top\">text 1</td></tr>" +
"<tr><td valign=\"top\" style=\"padding-right:16px\">•</td><td valign=\"top\">text 2</td></tr>" +
"</table>"
let attributedString = try! NSAttributedString(data: html.data(using: String.Encoding.utf8)!,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue,],
documentAttributes: nil)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With