iosobjective-cnsattributedstringnsparagraphstyle

Draw a line inside a UITextView - NSAttributedString


I wish to draw a customizable line inside a UITextView consisting of some text (using NSAttributedString)

Here's what I tried

NSString *unicodeStr = [NSString stringWithFormat:@"%C%C%C", 0x00A0, 0x0009, 0x00A0]; //nbsp, tab, nbsp
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:unicodeStr];
NSRange strRange = NSMakeRange(0, str.length);

NSMutableParagraphStyle *const tabStyle = [[NSMutableParagraphStyle alloc] init];
tabStyle.headIndent = 16; //padding on left and right edges
tabStyle.firstLineHeadIndent = 16;
tabStyle.tailIndent = -16;
NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter location:40 options:@{}]; //this is how long I want the line to be
tabStyle.tabStops = @[listTab];
[str  addAttribute:NSParagraphStyleAttributeName value:tabStyle range:strRange];
[str addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:2] range:strRange];

But no matter what value I provide for the tab stop location (40 in this case) and tailIndent (-16 here), the line only respects the headIndent and spans the entire UITextView width (minus the headIndent of course).

EDIT - I am pretty sure the issue is because I am not using the correct unicode chars (although they seem to be the logical choice). In case this gives someone a hint, if I add a space after the 2nd nbsp i.e. towards the end, the tab is limited to a single tab length


Solution

  • Is it your expected result?

    enter image description here enter image description here

    Can you try this:

    NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter location:self.textView.frame.size.width - tabStyle.firstLineHeadIndent + tabStyle.tailIndent options:@{}];
    

    And this is the full code:

    - (void) viewDidAppear:(BOOL)animated {
      [super viewDidAppear:animated];
      NSString *unicodeStr = @"\n\u00a0\t\t\n";
      NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:unicodeStr];
      NSRange strRange = NSMakeRange(0, str.length);
    
      NSMutableParagraphStyle *const tabStyle = [[NSMutableParagraphStyle alloc] init];
      tabStyle.headIndent = 16; //padding on left and right edges
      tabStyle.firstLineHeadIndent = 16;
      tabStyle.tailIndent = -70;
      NSTextTab *listTab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter location:self.textView.frame.size.width - tabStyle.headIndent + tabStyle.tailIndent options:@{}]; //this is how long I want the line to be
      tabStyle.tabStops = @[listTab];
      [str  addAttribute:NSParagraphStyleAttributeName value:tabStyle range:strRange];
      [str addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:2] range:strRange];
    
      NSAttributedString *htmlStr = [[NSAttributedString alloc] initWithData:[@"<h1>Lorem ipsum dolor sit er elit lamet</h1>" dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
    
      [str insertAttributedString:htmlStr atIndex:0];
      [str appendAttributedString:htmlStr];
    
      self.textView.attributedText = str;
    }