Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Attributed String does not work in CCLabelTTF #1153

Open
Zammy opened this issue Jan 8, 2015 · 18 comments
Open

[iOS] Attributed String does not work in CCLabelTTF #1153

Zammy opened this issue Jan 8, 2015 · 18 comments
Labels

Comments

@Zammy
Copy link

Zammy commented Jan 8, 2015

[SpriteBuilder 1.3.6, Cocos2D-Swift version 3.3.0-develop]

I have not manage to get CCLabelTTF to work with attributedString.
If you create a starting project with SpriteBuilder. Add Code Connection from the label and add label property in MainScene. Run this code:

    NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:@"Hello"];
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,2)];
    self.label.attributedString = attributedString;

What is expected is "He" to become red. What happens is a crash.

I can post more details but I believe everyone will be able to reproduce this.

@Zammy Zammy changed the title [iOS] Attributed String does not workin in CCLabelTTF [iOS] Attributed String does not work in CCLabelTTF Jan 8, 2015
@Zammy Zammy closed this as completed Jan 8, 2015
@Zammy Zammy reopened this Jan 8, 2015
@cocojoe
Copy link
Contributor

cocojoe commented Jan 8, 2015

Please can you retest in SB 1.4 Beta
http://forum.spritebuilder.com/t/spritebuilder-1-4-beta-release/2573

Thanks

@ghost
Copy link

ghost commented Jan 25, 2015

This is still broken in Cocos2d 3.4.3. Properties of an AttributedString are not being honored (such as font and paragraph styles) and setting a text foreground color causes a crash. It seems like CCLabelTTF is just seriously broken since v3.3. It was fine in v3.2.1 and maybe has something to do with very deep code in the renderer or drawing routines.

If you create a CCLabelTTF with an attributed string, there's no crash until you actually add it to the stage (scene). If you create one with an attributed string that has paragraph and font attributes but no NSForegroundColor attributes and -- for instance -- color the text using label.fontColor, then you will actually not crash but you will get a so-colored label that's missing the paragraph and font attrubutes set on the attributed string.

It is not sufficient to rely on using the CCLabel fontName, fontSize, fontColor becuase we want to be able to use an attributed string with varying attributes across different ranges of the string. We want to be able to have different colors, font sizes, paragraph setting, etc. like we used to have in Cocos2d 3.2.1. Please fix this -- it has caused me lots of grief in trying to get an app ready for the App Store on a high-profile project. Thanks.

@cocojoe
Copy link
Contributor

cocojoe commented Jan 26, 2015

@Birkemose Would you be able to look at this ? Thanks

@cocojoe cocojoe added the Bug label Jan 26, 2015
@Birkemose
Copy link
Contributor

Sure

On 26 Jan 2015, at 10:17, cocojoe notifications@github.com wrote:

@Birkemose https://github.com/Birkemose Would you be able to look at this ? Thanks


Reply to this email directly or view it on GitHub #1153 (comment).

@jonnyijapan
Copy link

I'm kind of depending on this feature too... well, I will test any fixes :-)

@Birkemose
Copy link
Contributor

I looked at this in 3.3, but was unable to find out why CCLabelTTF crashes.
I was under the impression it had been fixed in 3.4?

On 07 Feb 2015, at 19:30, jonnyijapan notifications@github.com wrote:

I'm kind of depending on this feature too... well, I will test any fixes :-)


Reply to this email directly or view it on GitHub #1153 (comment).

@Birkemose
Copy link
Contributor

I have been looking into this again, and my bad for thinking it was fixed.

Just to recap.
When launching cocos2d-tests-ios on ex. iPad2 (8.1), an exception is thrown in line 75 of CCLabelTTF.m.
I do not know the reason why, or if it has anything to do with this problem.

After that, almost any attempt to add a string with attributes, causes an unrecoverable crash in line 402 of CCLabelTTF.
Very basic attributed strings will work, but adding pretty much any attribute, will cause the crash.

Googling around a bit, leads me to believe it has something to do with the font setup, but I do not have sufficient experience with Core Text functionality, to know what to look for.

On 08 Feb 2015, at 16:06, Lars Birkemose lars.birkemose@gmail.com wrote:

I looked at this in 3.3, but was unable to find out why CCLabelTTF crashes.
I was under the impression it had been fixed in 3.4?

On 07 Feb 2015, at 19:30, jonnyijapan <notifications@github.com mailto:notifications@github.com> wrote:

I'm kind of depending on this feature too... well, I will test any fixes :-)


Reply to this email directly or view it on GitHub #1153 (comment).

@ghost
Copy link

ghost commented Feb 9, 2015

Thanks so much! Does someone else on the team have more insight perhaps? It definitely used to work fine, but whatever changes occurred in 3.3 or thereabouts have caused problems with this. The fact that it doesn't crash unless you actually add your label to the stage makes me think the issue is deep in the renderer, but is that a silly theory? I mean, you can create as many complex labels as you want but it's only if you want to see them that you crash. It worked fine in 3.2.1 at least. Would love for this functionality to return in the future! 😻

@jonnyijapan
Copy link

We should at least have a test case that can show that it did work in 3.2 but not since 3.x...
So it will be easier for anyone who wants to take on the task.

@Birkemose
Copy link
Contributor

I have a test case which works in older version. This should just be added to the iOS tests.

On 09 Feb 2015, at 18:12, jonnyijapan notifications@github.com wrote:

We should at least have a test case that can show that it did work in 3.2 but not since 3.x...
So it will be easier for anyone who wants to take on the task.


Reply to this email directly or view it on GitHub #1153 (comment).

@RobBoluga
Copy link
Contributor

The problem with attributes not being applied in iOS (all I've looked at so far) seems to be in NSMutableAttributedStringFixPlatformSpecificAttributes in Support/NSAttributedString+CCAdditions.m

For some reason, if not running on Android, it reapplies a font attribute to the string - but only the first font attribute it comes across and to the whole string (fullRange) - removing any changes to font size, etc later on in the string.
Commenting out lines 264 to 269 stops this, but the font attribute is then again set on the 'fullRange' on line 333 - so commenting that line is also required to make font size attributes work on iOS.

Hopefully that helps someone who fully understands what this method is trying to achieve to resolve the issues...

@sarah-j-smith
Copy link
Contributor

Just want to change the color? CCLabelBMFont might do what you need.

I did some fixes to CCLabelBMFont recently. That class always promised that you could apply effects to individual font char sprites but it was impossible because of the caching/re-use and new-line mangling that went on mean the index of the child didn't correspond to the string. That now works and I added a convenience method that allows you to get a list of the sprites for a range.

Note that the second pull request hasn't been accepted yet, and fixes some bugs relating to FooBar.bmfont style fonts used by SpriteBuilder.

@SRandazzo
Copy link
Contributor

One cause of this is a faulty comparison of NSAttributedString equality in CCLabelTTF
https://github.com/cocos2d/cocos2d-objc/blob/v3.4/cocos2d/CCLabelTTF.m#L159

if ( _attributedString.hash != attributedString.hash)
should be
if ( ![_attributedString isEqualToAttributedString: attributedString])

Patching this locally resolves the issue for me

@mstorch
Copy link

mstorch commented Jul 13, 2015

Any update on this issue? The solution from @SRandazzo did not work for me. I am also running v3.4.3 and observe the same crash when setting NSForegroundColorAttributeName on CCLabelTTF attributedStrings. Thanks!

@Birkemose
Copy link
Contributor

I am in the process of going through issues for the final release of 3.4.9, so hopefully this week

@mstorch
Copy link

mstorch commented Jul 13, 2015

Excellent, looking forward to the upcoming release. Please let me know if you need any help testing anything out!

@Birkemose
Copy link
Contributor

hash is guaranteed to be identical for identical strings, so comparing hash and using isEqualToString, should be the same. No idea why they chose to use hash

@AlexMishagin
Copy link

AlexMishagin commented Feb 21, 2017

@SRandazzo @Birkemose about crash: there is bug in NSMutableAttributedStringFixPlatformSpecificAttributes method in NSAttributedString+CCAdditions.m, as we see in line [string addAttribute:(id)kCTForegroundColorFromContextAttributeName value:(__bridge id)color range:fullRange]; for kCTForegroundColorFromContextAttributeName used 'color' (CGColorRef) as value, but as described in comment for this attribute (kCTForegroundColorFromContextAttributeName), value must be CFBooleanRef. It's why cocos2d code is crashing when user wants to use NSForegroundColorAttributeName attribute in attributed string. Value should be something like [NSNumber numberWithBool:YES].

@mstorch there is workaround (if you still interested :-))
for example if you have attributed string:
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:str];
instead of setting attribute like this:
[text addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:somerange];
you should use CoreText attribute name like this:

CGColorRef color = CGColorRetain([UIColor redColor].CGColor);
[text addAttribute:(id)kCTForegroundColorAttributeName value:(__bridge id)color range:somerange];
CGColorRelease(color);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants