NSAttributedString不适用于SCNText

我想在SceneKit场景中显示一些文本,其中字符具有不同的颜色。 SCNText的文档说明:

从属性字符串创建文本几何时,SceneKit根据字符串中的属性设置文本样式,SCNText对象的属性确定字符串中没有样式属性的部分的默认样式。

我试过这个,但它不起作用。 SCNText似乎忽略了我的字符串的属性。 我检查了我的NSAttributedString的内容是否正确,并将其添加到UILabel,它按预期显示。

为什么3D文字没有着色?

这是一个小型测试应用程序(来自Single View Application模板)和截图:

测试应用程序截图

#import "ViewController.h" #import  @interface ViewController () @end @implementation ViewController - (void) viewDidLoad { [super viewDidLoad]; NSAttributedString* str = [ViewController makeSomeText]; [self addSceneViewWithText: str]; [self addLabelWithText: str]; } + (NSMutableAttributedString*) makeSomeText { NSDictionary* redAttr = @{NSForegroundColorAttributeName : [UIColor redColor]}; NSDictionary* greenAttr = @{NSForegroundColorAttributeName : [UIColor greenColor]}; NSDictionary* blueAttr = @{NSForegroundColorAttributeName : [UIColor blueColor]}; NSAttributedString* redStr = [[NSAttributedString alloc] initWithString: @"red" attributes: redAttr]; NSAttributedString* greenStr = [[NSAttributedString alloc] initWithString: @"green" attributes: greenAttr]; NSAttributedString* blueStr = [[NSAttributedString alloc] initWithString: @"blue" attributes: blueAttr]; NSMutableAttributedString* str = [[NSMutableAttributedString alloc] init]; [str appendAttributedString: redStr]; [str appendAttributedString: greenStr]; [str appendAttributedString: blueStr]; return str; } - (void) addSceneViewWithText: (NSAttributedString*) string { SCNView* view = [[SCNView alloc] initWithFrame: self.view.bounds]; view.scene = [SCNScene scene]; view.backgroundColor = [UIColor grayColor]; view.autoenablesDefaultLighting = true; view.allowsCameraControl = true; SCNNode* root = view.scene.rootNode; [self.view addSubview: view]; SCNNode* cameraNode = [SCNNode node]; cameraNode.camera = [SCNCamera camera]; cameraNode.camera.automaticallyAdjustsZRange = true; [root addChildNode: cameraNode]; SCNText* text = [SCNText textWithString: string extrusionDepth: 3]; // text.firstMaterial.diffuse.contents = [UIColor yellowColor]; SCNNode* textNode = [SCNNode nodeWithGeometry: text]; textNode.rotation = SCNVector4Make (1, 0, 0, 0.5f); [root addChildNode: textNode]; SCNVector3 text_center; float dummy; [text getBoundingSphereCenter: &text_center radius: &dummy]; textNode.position = SCNVector3Make (-text_center.x, -text_center.y, -150); } - (void) addLabelWithText: (NSAttributedString*) string { CGRect bounds = self.view.bounds; UILabel* label = [[UILabel alloc] initWithFrame: CGRectMake (0, 50, bounds.size.width, 50)]; label.attributedText = string; label.textAlignment = NSTextAlignmentCenter; [self.view addSubview: label]; } - (void) didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end 

直接回答你的问题:“为什么3D文字没有着色?”

颜色可能不被视为“风格”的一部分,因为他们正在使用文档中的单词。 它可能也是错误的用词,因为它描述的是文本的质量,它在每个曾经使用过的地方都会弯曲和扭曲。

他们的意思很可能就是重量,对齐,下划线,删除线,字距调整和引导……这种性质的东西都是由SceneKit解释的。 但只有反复试验才能确定哪些有效,哪些无效。

Apple应提供一个表格,其中包含SceneKit识别和使用的文本属性/质量列表。

我可以在Core Text和NSAttributedString文档中找到的“样式”的唯一用法是建议那些框架考虑将每个段落的这些类型的质量分组,这在思考SceneKit文本时也几乎没有帮助。


编辑:关于3D和材料的其他内容,以防万一这对您来说是新闻:

3D中的“材质”可以创建颜色的印象,对光线的reflection,reflection和3D中对象上材质的其他质量,并且需要创建和应用。 它并不像在2D思维中那样简单地说“让objectABC变成红色”。

单个文本对象(用3D表示,而不是你如何看待Cocoa中的这些东西)可能无法用SceneKit中的不同材质和/或材质ID自动制作。 材质ID是在3ds Max等大多数人创建几何体和材质的东西中,不同材质应用于单个对象的不同部分的方式。

不幸的是,SceneKit不遵循这个约定,而是使用’elements’作为几何对象的一部分,每个对象都是索引的一部分,索引对应于提供该几何的任何材料。

你可以在这里阅读更多相关信息:

https://developer.apple.com/library/ios/documentation/SceneKit/Reference/SCNGeometry_Class/index.html#//apple_ref/doc/uid/TP40012000-CLSCHSCNGeometry-SW15

因此,为了得到你正在寻找的东西,你可能需要制作3个文本对象,并为每个文本对象提供你想要的颜色的独特材料, 或者将3个单词对象分解为3个元素,然后进行有趣的猜测如何在每一个上获得正确的材料。

编辑:忽略上段的最后一部分。 你需要制作3个文本对象才能获得你想要的外观。 场景工具包中的材质分布的元素function保留在文本对象上,因此您无法将单词级别的文本拆分为不同的元素。

来自docs:

文本几何可以包含一个,三个或五个几何元素:

  • 如果其extrusionDepth属性为0.0,则文本几何体的一个元素对应于其一个可见边。

  • 如果其拉伸深度大于零且其chamferRadius属性为0.0,则文本几何体具有三个元素,对应于其前面,后面和拉伸边。

  • 如果挤出深度和倒角半径均大于零,则文本几何体具有五个元素,对应于其前,后,挤出侧面,前倒角和后倒角。