2

I am trying to display some attributed text in a UITextView by using NSTextContainer and NSTextStorage but I don't see anything drawn in the textview (textview itself is drawn with white background as desired but no attributed text in it)

I however, can do it by just setting the .attributedText property of UITextView to my attributed text string but I want to know what I am doing wrong here or what concepts I misunderstood. Hopefully someone can explain.

- (void) test
{
    UIView *mainView = [[UIView alloc] initWithFrame:self.window.frame];
    mainView.translatesAutoresizingMaskIntoConstraints = NO;

    UITextView* textView = [[UITextView alloc] init];
    textView.translatesAutoresizingMaskIntoConstraints = NO;
    textView.backgroundColor = [UIColor whiteColor];

    [mainView addSubview:textView];
    [mainView removeConstraints:mainView.constraints];

    // layout constraints
    NSArray *constraintHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[textView]-|" options:0 metrics:nil views:@{@"textView":mainView.subviews[0]}];
    NSArray *constraintVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[textView(>=100)]" options:0 metrics:nil views:@{@"textView":mainView.subviews[0]}];

    [mainView addConstraints:constraintHorizontal];
    [mainView addConstraints:constraintVertical];

    NSString *data = @"This is some text where few words are colored and funky.  Some more garbage text. ";
    NSDictionary *attr = @{NSForegroundColorAttributeName:[UIColor redColor]};
    NSMutableAttributedString *textToShow = [[NSMutableAttributedString alloc] initWithString:data attributes:attr];

    NSRange r = {.location = 8, .length = 9};
    [textToShow addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:r];

    NSRange r2 = {.location = 23, .length = 4};
    [textToShow addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:r2];

    NSTextStorage* textStorage = [[NSTextStorage alloc]  initWithAttributedString:textToShow];

    CGSize cgs = textView.bounds.size;
    NSTextContainer *textcont = [[NSTextContainer alloc] initWithSize:cgs];

    // if i comment out these three lines and uncomment the
    //   following line (textView.attributedText .. ), then it works,
    NSLayoutManager *layoutManager = textView.layoutManager;
    [layoutManager addTextContainer:textcont];
    [textStorage addLayoutManager:layoutManager];

    //textView.attributedText = textToShow;

    textView.scrollEnabled = NO;

    UIViewController *vc = [[UIViewController alloc] init];
    vc.view = mainView;
    [vc.view layoutIfNeeded];
    self.window.rootViewController = vc;
}

Update There was no problem with the code above. I forgot to add the following lines to application:didFinishLaunchingWithOptions.. method (after looking at the code of the user with accepted answer below)

//self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
[self.window makeKeyAndVisible]; 
Nihat
  • 3,055
  • 3
  • 18
  • 28

1 Answers1

1

Your code works just fine for me (Xcode 5.0.2). Sample project is available here:

https://dl.dropboxusercontent.com/u/1365846/Test.zip https://dl.dropboxusercontent.com/u/1365846/Screen%20Shot%202014-02-09%20at%2023.11.22.png

According to the OP he was missing following lines:

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];

See comments.

plu
  • 1,321
  • 10
  • 14
  • I did as you suggested and still only white uitextview with no text whatsoever. Morever, I don't want to specify the size for I want it to be auto adjusted depending on the content of the text by using autolayout. By the way, I am using Xcode 5.0.2 as well. – Nihat Feb 09 '14 at 22:06
  • Just to clear up, do you mean that you see the colored text by saying "works fine"? It does not give any errors, it compiles and launches simulator, it just does not show. – Nihat Feb 09 '14 at 22:10
  • Hm weird. Here's the test project I've created, containing your code: https://dl.dropboxusercontent.com/u/1365846/Test.zip This is how it looks like: https://dl.dropboxusercontent.com/u/1365846/Screen%20Shot%202014-02-09%20at%2023.11.22.png – plu Feb 09 '14 at 22:11
  • Thank you! I had those lines missing because I had storyboards and just called that test method without thinking! self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window makeKeyAndVisible]; Please update your response to say that I forgot those. When people are looking for answer to similar problem, they can take notice of the real cause! – Nihat Feb 09 '14 at 22:21
  • Funny thing though why it would work when i just set the attributed text. But anyway, at least i know it is not because the way I was setting up textstorage and layoutmanager – Nihat Feb 09 '14 at 22:23