Search code examples
ioscore-textnstextattachmentnsparagraphstylenstexttab

NSAttributedString with image attachment and NSTextTab, text not aligned


I'm trying to have a UIlabel with an image and title on the left and a list of descriptions with bullets on the right.

To do that I'm using NSAttributedString like this :

NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init];
pStyle.tabStops =
    @[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:tabLocation options:[NSDictionary dictionary]] ];

NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:@"test_image"];
textAttachment.bounds = CGRectMake(0, -3, 15, 15);//resize the image
attString = [NSAttributedString attributedStringWithAttachment:textAttachment].mutableCopy;
[attString appendAttributedString:[[NSAttributedString alloc]
                                      initWithString:[NSString stringWithFormat:@"title\t\u2022 %@",
                                                                                [@[ @"description1", @"description2" ]
                                                                                    componentsJoinedByString:@"\n\t\u2022 "]]
                                          attributes:@{NSParagraphStyleAttributeName : pStyle}]];
label.attributedText = attString;

I expect the list on the right to be left aligned but that's not the case, here is the result I get:

enter image description here

What I expect is the list to be aligned like this:

enter image description here


Solution

  • The issue is with location parameter in NSTextTab

    • According to description, location parameter helps to position text from left margin. So this is what we needed, just replace below lines

      pStyle.tabStops =  @[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:tabLocation options:[NSDictionary dictionary]] ];
      

      with

      pStyle.tabStops = @[[[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:[self getTextLocationFor:@"test"]  options:[NSDictionary dictionary]] ];
      
    • Add getTextLocationFor: method to calculate location as follows

      -(CGFloat)getTextLocationFor:(NSString *)inputStr{
           CGSize maximuminputStringWidth = CGSizeMake(FLT_MAX, 30);
           CGRect textRect = [inputStr boundingRectWithSize:maximuminputStringWidth
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]}
                                              context:nil];
           UIImageView * testImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"close_red"]];//Change image name with yours
      
           return textRect.size.width + testImage.frame.size.width +2;
      }
      
    • That's it we are ready to go run your project now everything will be fine.

    RESULT:

    enter image description here