NSAttributedString and html style (bullet alignment)

In my iOS application, I use NSAttributedString to create a list of bullets. Unfortunately, I struggle to make bullets look presentable. My first attempt was to use plain text and a unicode character for a bullet, mostly using a line 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 is the following:

enter image description here

I like the look of the bullets, but the overflow text in the last pool should be aligned with the previous line, and I could not figure out how to achieve this with plain text (without applying the same alignment to the paragraph above).

My second attempt was to use html in NSAttributedString via NSHTMLTextDocumentType and use the <ul> and <li> elements to create the bullet.

 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 ) 

This fixed the first problem, but introduced a new one:

enter image description here

The bullets are now too far away (both left and right). I tried using typical html / css tricks to fix the alignment ( <li style="text-indent: -10px;"> ), but these styles seem to be ignored by NSAttributedString.

I tried to fix this with an optional 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:

enter image description here

As you can see, this only exacerbated the situation, here are my problems:

  • This compensates for the second line, but I want only this effect for the bullet, and not before the paragraph (I think I can fix this by reducing the range over which the effect is applied).
  • I need to guess / correct the offset, in my example I selected 20, and this was not enough for the bullet, given the current font settings, which could
  • For some reason, the distance between the bullets is even more stretched now without any reason, it seems that just by applying vanilla NSParagraphStyle without doing anything, and I see no way to fix it.

All I really want is that my spacing between the bullets looks like the first screen shot, while the indentation of the overflow of the second line looks like the second, without the need for hard coding of the exact pixel positions. Could you guys help me?

thanks

+7
ios objective-c cocoa-touch swift nsattributedstring
source share
1 answer

I had to add custom styles to the list, and this is the paragraph style I used for each bullet in NSAttributedString

headIndent and firstLineHeadIndent can be changed, but the location of NSTextTab should be the same as headIndent

 NSMutableParagraphStyle *const bulletParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; bulletParagraphStyle.headIndent = 60; bulletParagraphStyle.firstLineHeadIndent = 30; NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural location:60 options:@{}]; bulletParagraphStyle.tabStops = @[listTab]; 

This works if your marker point has \t after it (and then the text)

+4
source share

All Articles