Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSMutableAttributedString crashing on changing the font?

I'm sure mutable means it can be changed, so why's this happening?

attrString = [[NSMutableAttributedString alloc] initWithString:@"Tip 1: Aisle Management The most obvious step – although one that still has not been taken by a disconcerting number of organisations – is to configure cabinets in hot and cold aisles. If you haven’t got your racks into cold and hot aisle configurations, we can advise ways in which you can achieve improved airflow performance."];

        [attrString setFont:[UIFont systemFontOfSize:20] range:NSMakeRange(0, 23)];
        [attrString setFont:[UIFont systemFontOfSize:15] range:NSMakeRange(24, 325)];
        [attrString setTextColor:[UIColor blackColor] range:NSMakeRange(0,184)];
        [attrString setTextColor:[UIColor blueColor] range:NSMakeRange(185,325)];
        break;

Both my catextlayer and my nsmutableattributedsring are defined in my header file. I make the changes to my string above in a switch, then call this code to update the catextlayer the string is shown in:

//updates catext layer
TextLayer = [CATextLayer layer];

TextLayer.bounds = CGRectMake(0.0f, 0.0f, 245.0f, 290.0f);
TextLayer.string = attrString;
TextLayer.position = CGPointMake(162.0, 250.0f);
TextLayer.wrapped = YES;

[self.view.layer addSublayer:TextLayer];

It crashes on when it tries to set the font, but I cant work out why?

-[NSConcreteMutableAttributedString setFont:range:]: unrecognized selector sent to instance 0xd384420 * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMutableAttributedString setFont:range:]: unrecognized selector sent to instance 0xd384420'

Why is this happening?

like image 593
dev6546 Avatar asked Sep 20 '12 17:09

dev6546


2 Answers

NSMutableAttributedString doesn't have a setFont:range: function.

Taken from here.... iphone/ipad: How exactly use NSAttributedString?

So I did a bit of reading from the docs.

The functions is...

[NSMutableAttirbutedString setAttributes:NSDictionary range:NSRange];

So you should be able to do something like this...

[string setAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Helvetice-Neue"]} range:NSMakeRange(0, 2)];

or

[string setAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"Helvetice-Neue"], NSFontAttributeName", nil] range:NSMakeRange(0, 2)];

if you're still using old ObjC syntax.

Hope that helps.

like image 105
Fogmeister Avatar answered Nov 19 '22 13:11

Fogmeister


First of all,Is the attrString you said a property?If it's a property,you'd better check that have you declared the property with the copy attribute, and are you presumably using the compiler-generated setter? If YES The compiler-generated setter sends the copy message to the object to make a copy. The copy message makes an immutable copy. That is, it creates an NSAttributedString, not an NSMutableAttributedString.

One way to fix this is to write your own setter that uses mutableCopy, like this if you're using ARC:

- (void)setTextCopy:(NSMutableAttributedString *)text {
   textCopy = [text mutableCopy];
}

or like this if you're using manual reference counting:

- (void)setTextCopy:(NSMutableAttributedString *)text {
    [textCopy release];
    textCopy = [text mutableCopy];
}

Another fix would be to make textCopy be an NSAttributedString instead of an NSMutableAttributedString, and make the rest of your code work with it as an immutable object.

Reference: 1️⃣How to copy a NSMutableAttributedString 2️⃣NSConcreteAttributedString mutableString crash

like image 38
ChenYilong Avatar answered Nov 19 '22 11:11

ChenYilong