我以编程方式生成一组UILabels
,将它们附加到SCNNodes
然后将它们放在场景中。
问题是某些标签上的文字没有出现。这似乎是(似乎)随机发生的。
这是代码:
var labels = [SCNNode]()
var index: Int
var x: Float
var y: Float
let N = 3
for i in 0 ... N-1 {
for k in 0 ... N-1 {
let node = label()
labels.append(node)
index = labels.count - 1
x = Float(i) * 0.5 - 0.5
y = Float(k) * 0.5 - 0.5
sceneView.scene.rootNode.addChildNode(labels[index])
labels[index].position = SCNVector3Make(x, y, -1)
}
}
以及创建标签节点的方法:
func label() -> SCNNode {
let node = SCNNode()
let label = UILabel(frame: CGRect(x: CGFloat(0), y: CGFloat(0),
width: CGFloat(100), height: CGFloat(50)))
let plane = SCNPlane(width: 0.2, height: 0.1)
label.text = "test"
label.adjustsFontSizeToFitWidth = true
plane.firstMaterial?.diffuse.contents = label
node.geometry = plane
return node
}
标签本身总是正确显示,只是其中一些是空白的,没有文字。
我试过玩标签的大小,它附着的平面大小,字体大小等 - 似乎没什么用。
我也尝试将标签创建封装在DispatchQueue.main.async { ... }
中,这也没有帮助。
我是 Swift 和 iOS 的新手,所以很容易错过一些非常明显的东西。
提前致谢!
编辑:
(1)设置label.backgroundColor = UIColor.magenta
清楚地表明实际上没有创建标签,但节点/平面是。
有些标签是白色的(i.e 只有SCNNode
正在被渲染),但是在短暂的延迟后,它们有时会变成洋红色并且文本会出现。但是有些标签仍然缺失。
(2)进一步看来,它与节点(标签)相对于摄像机的位置和方向有关。我创建了一个大的(10x10)标签网格,然后测试将相机放在网格中的不同初始位置。节点出现的可能性似乎与节点距初始摄像机位置的距离直接相关。直接在摄像机前面的那些节点总是被渲染,而那些遥远的节点几乎从未被渲染过。
(3)workaround/hack 是将标签转换为图像,而是使用它们 - 如果有人感兴趣,代码是https://github.com/Jordan-Campbell/uiimage-arkit-testing。
2 回答
如果您在 AR 中标记事物,99%的情况下最好在**“屏幕空间”**而不是“透视”中这样做。
屏幕空间中标签的好处:
无论用户与标签的距离如何,始终可读
您可以使用常规 UILabel,无需将它们绘制到图像,然后将图像映射到 SCNPlane。
您的应用程序会有第一方的感觉,因为 Apple 在其所有 AR 应用程序中使用 Screen Space 作为其标签(请参阅 Measure)。
您将能够在 UILabel 上使用标准动画,在使用 Perspective 中的内容时动画设置要复杂得多。
如果您在屏幕空间上出售,请告诉我,我会很乐意提供一些代码,向您展示基础知识。
DispatchQueue.main.async {
}