Search code examples
iosxcodeuitextviewtraitsnsattributedstring

-[UITextView setAttributedText:] stops working, when I use UITraitCollection variations


I have a UITextView set to display different attributed strings, depending on the device being used. But as soon as i am using traits, setText: doesn't work anymore.

I don't know where the information for the two texts are stored either. When I look at the storyboard I see:

<textView>
    <attributedString key="attributedText">
        <fragment content="Large">
            <attributes>
                <font key="NSFont" metaFont="system" size="14"/>
                <paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
            </attributes>
        </fragment>
    </attributedString>
    <variation key="heightClass=regular-widthClass=compact">
        <attributedString key="attributedText">
            <fragment content="Compact">
                <attributes>
                    <font key="NSFont" size="12" name=".AppleSystemUIFont"/>
                    <paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
                </attributes>
            </fragment>
        </attributedString>
    </variation>
</textView>

But how do I access (and change) this variation at runtime ?

How to reproduce:

I have the most simple setup. I let Xcode generate me a single view application. Then I place two UITextViews into the Main.storyboard. One is using a different text selected on UITraitCollection compact.

Xcode Screeny

Now I add two outlets to the ViewController and write some code in viewDidLoad to change the contents.

@interface ViewController : UIViewController

@property( assign, nonatomic) IBOutlet UITextView   *textView;  // traits   
@property( assign, nonatomic) IBOutlet UITextView   *textView2; // no traits

@end


@implementation ViewController

- (void)viewDidLoad
{
   [super viewDidLoad];

   NSParameterAssert( [self.textView isKindOfClass:[UITextView class]]);
   NSParameterAssert( [self.textView2 isKindOfClass:[UITextView class]]);
   NSParameterAssert( self.textView != self.textView2);

  [self.textView setText:@"XXXX"];  // does not show up
  [self.textView2 setText:@"XXXX"]; // works as expected

}

Using -setAttributedText: doesn't make a difference.

Download Xcode project


Solution

  • I think, the problem might be, that changing the text in viewDidLoad() is too early. I guess the changes are overwritten at some point later when the size classes / variations are applied.

    I was able to kinda workaround this by changing the text in viewDidLayoutSubviews() instead of viewDidLoad().