关于ios:NSAttributedString不适用于SCNText

NSAttributedString doesn't work with SCNText

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

When you create a text geometry from an attributed string, SceneKit styles the text according to the attributes in the string, and the properties of the SCNText object determine the default style for portions of the string that have no style attributes.

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

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

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

Screenshot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#import"ViewController.h"

#import <SceneKit/SceneKit.h>

@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文档中可以找到" style "的唯一用法,建议这些框架考虑将单词按段落划分为此类质量的单词,这在考虑SceneKit文本时也几乎没有帮助。

编辑:有关3D和材质的其他信息,以防万一这对您来说是个新闻:

3D语言中的

\\'Materials \\'可以在3D对象上创建色彩印象,对光的响应,反射性和其他质量的对象,因此需要创建和应用。这并不像说二维思维中那样简单地说"使objectABC为红色"。

单个文本对象(以3D方式表达,而不是您如何看待可可中的这些东西)可能无法通过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个文本对象才能获得想要的外观。 Scene Kit中材质分布的元素功能保留在"文本对象"上,因此您无法将单词级别的文本分解为不同的元素。

来自文档:

A text geometry may contain one, three, or five geometry elements:

  • If its extrusionDepth property is 0.0, the text geometry has one
    element corresponding to its one visible side.

  • If its extrusion depth is greater than zero and its chamferRadius
    property is 0.0, the text geometry has three elements, corresponding
    to its front, back, and extruded sides.

  • If both extrusion depth and chamfer radius are greater than zero, the
    text geometry has five elements, corresponding to its front, back,
    extruded sides, front chamfer, and back chamfer.