NSAttributedString 不适用于 SCNText [英] NSAttributedString doesn't work with SCNText

查看:39
本文介绍了NSAttributedString 不适用于 SCNText的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 SceneKit 场景中显示一些文本,其中角色具有不同的颜色.

#import "ViewController.h"#import @interface 视图控制器 ()@结尾@实现视图控制器-(无效)viewDidLoad{[超级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" 属性: redAttr];NSAttributedString* greenStr = [[NSAttributedString alloc] initWithString: @"green" 属性: greenAttr];NSAttributedString* blueStr = [[NSAttributedString alloc] initWithString: @"blue" 属性: blueAttr];NSMutableAttributedString* str = [[NSMutableAttributedString alloc] init];[str appendAttributedString: redStr];[str appendAttributedString: greenStr];[str appendAttributedString: blueStr];返回字符串;}- (void) addSceneViewWithText: (NSAttributedString*) 字符串{SCNView* view = [[SCNView alloc] initWithFrame: self.view.bounds];view.scene = [SCNScene 场景];view.backgroundColor = [UIColor grayColor];view.autoenablesDefaultLighting = true;view.allowsCameraControl = true;SCNNode* root = view.scene.rootNode;[self.view addSubview: view];SCNNode* cameraNode = [SCNNode 节点];cameraNode.camera = [SCNCamera 相机];cameraNode.camera.automaticallyAdjustsZRange = true;[root addChildNode: cameraNode];SCNText* text = [SCNText textWithString: 字符串挤压深度: 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;漂浮假人;[text getBoundingSphereCenter: &text_center radius: &dummy];textNode.position = SCNVector3Make (-text_center.x, -text_center.y, -150);}- (void) addLabelWithText: (NSAttributedString*) 字符串{CGRect 边界 = self.view.bounds;UILabel* label = [[UILabel alloc] initWithFrame: CGRectMake (0, 50, bounds.size.width, 50)];label.attributedText = 字符串;label.textAlignment = NSTextAlignmentCenter;[self.view addSubview: 标签];}- (void) didReceiveMemoryWarning{[超级 didReceiveMemoryWarning];}@结尾

解决方案

直接回答您的问题:为什么 3D 文本没有着色?"

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

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

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

我可以在 Core Text 和 NSAttributedString 文档中找到的样式"的唯一用法表明,这些框架考虑使用这个词来对每个段落的这些类型的质量进行分组,这在考虑 SceneKit 文本时也几乎没有帮助.<小时>

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

3D 中的材料"在 3D 对象上创建颜色印象、对光的响应、反射率和材料的其他质量,需要创建和应用.不像在 2D 思维中那样说让 objectABC 变红"那么简单.

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

不幸的是,SceneKit 没有遵循这个约定,而是使用元素"作为几何对象的一部分,每个元素都是索引的一部分,该索引对应于您提供该几何的任何材料.

您可以在此处阅读更多相关信息:

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 中素材分布的元素特性是保留在Text Objects 上的,所以你不能把文字在word 级别分解成不同的Element.

来自文档:

<块引用>

一个文本几何可能包含一个、三个或五个几何元素:

  • 如果它的exgressionDepth属性为0.0,则文本几何体有一个元素对应于其可见的一侧.

  • 如果它的挤压深度大于零并且它的倒角半径属性为0.0,文本几何有3个元素,对应到它的正面、背面和挤压的侧面.

  • 如果挤压深度和倒角半径都大于零,则文本几何有五个元素,分别对应于它的正面、背面、挤压侧面、前倒角和后倒角.

I want to display some text inside a SceneKit scene, where the characters have a different color. The documentation of SCNText states:

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.

I tried this but it doesn't work. SCNText seems to ignore the attributes of my string. I checked if the content of my NSAttributedString is correct and added it to an UILabel, where it displays as intended.

Why is the 3D text not colored?

Here is a small test application (from the Single View Application template) and a screenshot:

#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

解决方案

In direct answer to your question: "Why is the 3D text not colored?"

Colour is probably not considered part of the "style" as they're using the word in the docs. It's probably also the wrong word to be using, since it's a description of qualities of text that gets bent and twisted in every place it's ever used.

It's likely what they mean to say is things like weight, alignment, underlining, strikethroughs, kerning and leading... things of that nature are interpreted by SceneKit. But only trial and error will find for sure what does and does not work.

Apple should be providing a table with a list of attributes/qualities of text recognised and used by SceneKit.

The only use of "style" I can find in the Core Text and NSAttributedString docs suggest those frameworks consider the word to group these sorts of qualities per paragraph, which is also little to no help when thinking about SceneKit text.


Edit: Additional stuff about 3D and Materials, just in case this is news to you:

'Materials' in 3D speak create the impressions of colour, response to light, reflectiveness and other qualities of a material on an object in 3D, and need to be created and applied. It's not nearly as simple as saying "make objectABC be red" as it is in 2D thinking.

A single text object (in 3D speak, not how you think of these things in Cocoa) probably wouldn't have a way to automagically be made with different materials and/or Material IDs within SceneKit. Material IDs are how different materials are applied to different portions of a single object in things like 3ds Max where most people create geometry and materials.

Unfortunately SceneKit doesn't follow this convention, instead using 'elements' as a part of geometry objects, each of which is part of an index that corresponds to whatever materials your providing that geometry.

You can read more about this here:

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

So to get what you're looking for you're probably going to need to make 3 text objects and give each a unique material of the colour you're wanting, or break the 3 word object up into 3 elements and then have fun guessing how to get the right material onto each of them.

EDIT: Ignore last part of above paragraph. You need to make 3 text objects to get the look you're after. The elements feature of material distribution in Scene Kit is reserved on Text Objects, so you can't break up the text at the word level into differing Elements.

From docs:

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.

这篇关于NSAttributedString 不适用于 SCNText的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆