首页 文章

使用 ARKit 时不显示 UILabel 文本

提问于
浏览
2

我以编程方式生成一组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 回答

  • 1

    如果您在 AR 中标记事物,99%的情况下最好在**“屏幕空间”**而不是“透视”中这样做。

    屏幕空间中标签的好处:

    • 无论用户与标签的距离如何,始终可读

    • 您可以使用常规 UILabel,无需将它们绘制到图像,然后将图像映射到 SCNPlane。

    • 您的应用程序会有第一方的感觉,因为 Apple 在其所有 AR 应用程序中使用 Screen Space 作为其标签(请参阅 Measure)。

    • 您将能够在 UILabel 上使用标准动画,在使用 Perspective 中的内容时动画设置要复杂得多。

    如果您在屏幕空间上出售,请告诉我,我会很乐意提供一些代码,向您展示基础知识。

  • 0
    • 使用主线程为场景创建和添加标签。这将使事情变得更快,并且避免将此添加与平面检测耦合到场景,这实际上减慢了渲染速度。这有时会起作用。

    DispatchQueue.main.async {

    }

    • 使用 UIView SuperView 作为您的标签的父级,这将使事情更顺畅。

相关问题