使用ARKit时不显示UILabel文本

时间:2017-11-21 06:12:21

标签: ios swift uilabel arkit

我以编程方式生成一组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表明事实上标签没有被创建,但是节点/平面是。

有些标签是白色的(即只有SCNNode正在渲染),但是在短暂的延迟之后,它们有时会变成洋红色并且文本会出现。但是有些标签仍然缺失。

(2)进一步看来,它与节点(标签)相对于摄像机的位置和方向有关。我创建了一个大的(10x10)标签网格,然后测试将相机放在网格中的不同初始位置。节点出现的可能性似乎与节点距初始摄像机位置的距离直接相关。直接在摄像机前面的那些节点总是被渲染,而那些遥远的节点几乎从未被渲染过。

(3)变通方法/黑客是将标签转换为图像,并使用它们 - 如果有人感兴趣,代码位于https://github.com/Jordan-Campbell/uiimage-arkit-testing

2 个答案:

答案 0 :(得分:1)

如果您要在AR中标记事物,那么在99%的情况下,最好在“屏幕空间” 中进行标记,而不是在“透视”中进行标记。

屏幕空间中标签的优点:

  1. 始终可读,无论用户离标签的距离如何
  2. 您可以使用常规的UILabel,无需将它们绘制到图像上,然后将图像映射到SCNPlane。
  3. 您的应用将具有第一手的感觉,因为Apple在所有AR应用中都将Screen Space用作其标签(请参阅Measure)。
  4. 您将能够在UILabel上使用标准动画,而在Perspective中使用内容时,设置动画要复杂得多。

如果您在Screen Space上出售,请告诉我,我们很乐意提供一些代码向您展示基本知识。

答案 1 :(得分:0)

  1. 使用主线程创建标签并将其添加到场景。这将使事情变得更快,并且避免将此添加项与场景与平面检测结合使用,这确实会减慢渲染速度。有时会起作用。

DispatchQueue.main.async {

}

  1. 在标签上使用UIView SuperView作为Parent可以使事情变得更加顺畅。