tangqiaoboy / iOS-Pro

《 iOS 开发进阶》随书示例程序和勘误
773 stars 231 forks source link

下载的CoreTextDemo中定制文字颜色无效问题 #24

Open kepuna opened 8 years ago

kepuna commented 8 years ago

大神您好,最近在拜读您的 《基于 CoreText 的排版引擎:基础》,然后https://raw.githubusercontent.com/tangqiaoboy/iOS-Pro/master/DemoProjects/CoreText.zip 下载的CoreTextDemo里面,我测试的时候发现,通过range修改富文本的颜色无效,但是设置富文本的字体大小有效果!麻烦您能测试看一下吗?

测试步骤如下:

  1. 下载了CoreText的zip包
  2. 将ViewController里viewDidload的代码改成如下代码即可,我测试的时候,文字颜色改变不了,但是我将设置颜色改成设置字体大小可以生效

    • (void)viewDidLoad { [super viewDidLoad];

    CTFrameParserConfig *config = [[CTFrameParserConfig alloc] init]; config.width = self.ctView.width; config.textColor = [UIColor blackColor];

    NSString content = @" 对于上面的例子,我们给 CTFrameParser 增加了一个将 NSString 转 " " 换为 CoreTextData 的方法。" " 但这样的实现方式有很多局限性,因为整个内容虽然可以定制字体 " " 大小,颜色,行高等信息,但是却不能支持定制内容中的某一部分。" " 例如,如果我们只想让内容的前三个字显示成红色,而其它文字显 " " 示成黑色,那么就办不到了。" "\n\n" " 解决的办法很简单,我们让CTFrameParser支持接受 " "NSAttributeString 作为参数,然后在 NSAttributeString 中设置好 " " 我们想要的信息。"; NSDictionary attr = [CTFrameParser attributesWithConfig:config]; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:content attributes:attr]; [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 7)];

    CoreTextData *data = [CTFrameParser parseAttributedContent:attributedString config:config]; self.ctView.data = data; self.ctView.height = data.height; self.ctView.backgroundColor = [UIColor yellowColor]; }

yngty commented 7 years ago

我用C语言那套可以换用OC的变不了

BackWorld commented 7 years ago

走的是json文件里的颜色样式,当然config里的textColor不起作用了。。。

{ "color" : "red",
  "content" : " 内容、颜色、字体 ",
  "size" : 22,
  "type" : "txt"
  }

在parser类里解析的时候将"red"字符转换为[UIColor redColor],否则的话是默认的灰色。

CTFrameParser.m第152行:

+ (UIColor *)colorFromTemplate:(NSString *)name {
    if ([name isEqualToString:@"blue"]) {
        return [UIColor blueColor];
    } else if ([name isEqualToString:@"red"]) {
        return [UIColor redColor];
    } else if ([name isEqualToString:@"black"]) {
        return [UIColor blackColor];
    } else {
        return nil;
    }
}
yizibi commented 7 years ago

@tangqiaoboy, 确实是必须通过Coretext下,才能变换颜色,我还找了好久原因; @younghaopro NSDictionary *attributes = [LXCTFrameSeting attributesWithConfig:config];

NSMutableAttributedString *attrbuteString = [[NSMutableAttributedString alloc] initWithString:content attributes:attributes];

[attrbuteString addAttribute:**(__bridge id)kCTForegroundColorAttributeName** value:[UIColor redColor] range:NSMakeRange(0, 7)];

LXCTTextData *data = [LXCTFrameSeting frameSettingWithAttributedContent:attrbuteString config:config];

但是,为什么只有通过CoreText下,才能成功呢????

tangqiaoboy commented 7 years ago

因为CTFrameParser.m里面忽略了attribute信息。其实源码都在,可以自己分析实现原理的。

lucy notifications@github.com于2017年8月11日 周五下午2:28写道:

@tangqiaoboy https://github.com/tangqiaoboy, 确实是必须通过Coretext下,才能变换颜色,我还找了好久原因; @younghaopro https://github.com/younghaopro NSDictionary *attributes = [LXCTFrameSeting attributesWithConfig:config];

NSMutableAttributedString *attrbuteString = [[NSMutableAttributedString alloc] initWithString:content attributes:attributes];

[attrbuteString addAttribute:(__bridge id)kCTForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 7)];

LXCTTextData *data = [LXCTFrameSeting frameSettingWithAttributedContent:attrbuteString config:config];

但是,为什么只有通过CoreText下,才能成功呢????

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/tangqiaoboy/iOS-Pro/issues/24#issuecomment-321739828, or mute the thread https://github.com/notifications/unsubscribe-auth/AAsvqVpawPNCj8V3qXLXjY7-wt4evnR9ks5sW_SPgaJpZM4KSNdF .

-- Tang Qiao

AndyUkJ commented 6 years ago

如果忽略了attribute信息,但是NSBackgroundColorAttributeName起作用,为什么NSForegroundColorAttributeName不起作用?

AndyUkJ commented 6 years ago

@tangqiaoboy 为什么不直接解释明白呢,毕竟按照书中的代码来测试,必然会出现这样的问题。

AndyUkJ commented 6 years ago

我验证了一下: [attributedString addAttribute:((__bridge id)kCTForegroundColorAttributeName) value:[UIColor blueColor] range:NSMakeRange(0, 40)]; [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(0, 40)]; 如果设置了kCTForegroundColorAttributeName,那么再设置NSForegroundColorAttributeName就不起作用。 所以前后要一致。这个问题同样存在于:TTTAttibuteLabel的使用上。

请参考:http://gilnuy.github.io/2016/04/19/kCTForegroundColorAttributeName%E5%92%8CNSForegroundColorAttributeName/

另外交换顺序,即先执行NSForegroundColorAttributeName再执行kCTForegroundColorAttributeName,还是显示kCTForegroundColorAttributeName的结果。 所以可以理解为kCTForegroundColorAttributeName的优先级高于NSForegroundColorAttributeName。

但是在唐大神的书里,为什么里外用的两种,不知道大神是如何避免这个问题的。我和楼上网友遇到的是一样的问题。

至于内部原因,我还没弄明白。我搞清楚了,会发出来。 如果哪位大神了解,请指教。

@younghaopro @lucyios

tangqiaoboy commented 6 years ago

这应该是coretext内部的一些规则细节。这个demo是告诉大家如果做出一个排版引擎

huaweiluo notifications@github.com于2018年9月9日 周日上午9:59写道:

我验证了一下: [attributedString addAttribute:((__bridge id)kCTForegroundColorAttributeName) value:[UIColor blueColor] range:NSMakeRange(0, 40)]; [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(0, 40)];

如果设置了kCTForegroundColorAttributeName,那么再设置NSForegroundColorAttributeName就不起作用。 所以前后要一致。这个问题同样存在于:TTTAttibuteLabel的使用上。

请参考: http://gilnuy.github.io/2016/04/19/kCTForegroundColorAttributeName%E5%92%8CNSForegroundColorAttributeName/

至于内部原因,我还没弄明白。我搞清楚了,会发出来。 如果哪位大神了解,请指教。

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/tangqiaoboy/iOS-Pro/issues/24#issuecomment-419685120, or mute the thread https://github.com/notifications/unsubscribe-auth/AAsvqf_OZhRlFXSe7iSseJDAsKXtJ7PLks5uZHYGgaJpZM4KSNdF .

-- Tang Qiao

AndyUkJ commented 6 years ago

@tangqiaoboy 您的《ios开发进阶》、《ios面试之道》我都购买了。所谓三人行必有我师,收获还是不少的,谢谢分享!谢谢回复!coretext内部规则,我后续抽空再研究吧。