【问题标题】:UILabel text doesn't appear when using ARKit使用 ARKit 时不显示 UILabel 文本
【发布时间】:2018-05-04 12:25:11
【问题描述】:

我正在以编程方式生成一组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) 解决方法/hack 是将标签转换为图像,然后使用它们 - 如果有人感兴趣,代码位于 https://github.com/Jordan-Campbell/uiimage-arkit-testing

【问题讨论】:

  • 您是否检查过您没有尝试将两个节点放在同一位置?我有一个类似的问题,其中一些出现而另一些没有出现,正是因为如此。
  • 可能导致此问题的另一件事是,它可能会在呈现标签之前将标签从内存中丢失,如果您查看 Apple 文档,他们建议您的对象不要在函数内部声明,而是在一个类的记忆周期。
  • 嗨,是的,在 AR 中渲染标签并不是很好——其中很多实际上取决于标签在渲染时相对于相机的角度。我发现最好的办法是将内容绘制到UIImage,然后将其附加到SCNPlane

标签: ios swift uilabel arkit


【解决方案1】:

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

标签在屏幕空间中的好处:

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

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

【讨论】:

  • 我会对一个例子感兴趣:)
  • 我认为有很多理由在 AR 中创建标签 - 特别是考虑到 AR 的主要好处之一是它打开了大量的虚拟空间,因此您可以明确避免填满屏幕.无论如何,我作为对我的问题的编辑发布的解决方案现在已成为大多数人的默认标准(他们都独立发现了解决方案)。
  • (...继续我上面的评论)-您的要点肯定是正确的,但是我认为这不会影响您在 AR 中显示信息所获得的好处。每个人在不同的时间都有自己的优点。
  • Jordan - 从技术上讲,屏幕空间仍在“AR”中显示标签,标签仍然具有空间坐标,但是,它的显示方式使其易于阅读。
  • 这是我就该主题制作的完整 youtube 教程的链接:youtube.com/watch?v=itXUZmKCv_Q&t=4s
【解决方案2】:
  1. 使用主线程创建标签并将其添加到场景中。这将使事情变得更快,并避免将此添加到场景与平面检测相结合,这确实会减慢渲染速度。这有时有效。

DispatchQueue.main.async {

}

  1. 将 UIView SuperView 用作标签的父级,这会使事情变得更顺畅。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    相关资源
    最近更新 更多