【问题标题】:ARKit: How can I add a UIView to ARKit Scene?ARKit:如何将 UIView 添加到 ARKit 场景?
【发布时间】:2018-07-19 22:26:37
【问题描述】:

我正在使用 ARKit 开发一个 AR 项目。

我想在 ARKit 场景中添加一个 UIView。当我点击一个对象时,我想在对象旁边以“弹出窗口”的形式获取信息。此信息位于 UIView 中。

是否可以将此 UIView 添加到 ARKit 场景? 我将此 UIView 设置为场景,然后我该怎么办? 我可以给它一个节点,然后将它添加到 ARKit 场景中吗?如果是这样,它是如何工作的?

或者还有其他方法吗?

谢谢!

编辑:我的 SecondViewController 的代码

class InformationViewController: UIViewController {

    @IBOutlet weak var secondView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = secondView
    }
}

编辑 2:firstViewController 中的代码

guard let secondViewController = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else {
    print ("No secondController")
    return
}

let plane = SCNPlane(width: CGFloat(0.1), height: CGFloat(0.1))       
plane.firstMaterial?.diffuse.contents = secondViewController.view

let node = SCNNode(geometry: plane)

我只得到飞机的白屏,而不是视图。

【问题讨论】:

  • 您的意思是要在现实世界中以 3D 形式显示信息吗?或者您希望将信息与另一个视图控制器的 segue 一起显示?
  • 我想把它放在现实世界中的 3D 中。
  • 正如 Lësha 上面提到的,在 iOS 12.1.x 之前工作得非常好之后,如果你需要关闭在 SCNPlane 中呈现 UIViews 的 UIViewController,那么最终会发生什么,前三分之二您的屏幕将对触地事件无响应。今天早些时候提交了这个错误。
  • @TeodorIuliuRadu 您是否同时发现了更多信息?我在 12.2 测试版中,识别器对我根本不起作用._.

标签: ios iphone swift uiview arkit


【解决方案1】:

我现在无法为您提供代码,但这是如何做到的。

  1. 创建SCNPlane
  2. 使用您需要的所有元素创建您的UIView
  3. UIView 创建图像上下文。
  4. 将此图像用作SCNPlane 的素材。

或者更容易制作带有标签的SKScene 并将其添加为SCNPlane 的材料。

【讨论】:

  • 非常感谢!如何从 UIView 创建图像上下文?
  • 很抱歉我现在不能给你任何东西。您可以在 stackoverflow 上轻松找到从 uiview 创建图像
  • 非常感谢!我的问题是现在我不能调用视图。它不适用于 ViewController。
  • 你用过/看过 twitter ar 应用吗?这种方法是相似的(这就是我的想法)。您可以将 UIView 显示为平面的材料。并将其他节点(平面)作为按钮。您可以通过点击用作按钮的节点来更改 UIView 的元素并更改平面的材质。
  • 我认为 Lësha Turkowski 的方法正是您所需要的。
【解决方案2】:

要将文本放置在世界中的标签中,请将其绘制成图像,然后将该图像附加到SCNNode

例如:

let text = "Hello, Stack Overflow."
let font = UIFont(name: "Arial", size: CGFloat(size))
let width = 128
let height = 128

let fontAttrs: [NSAttributedStringKey: Any] = 
[NSAttributedStringKey.font: font as UIFont]

let stringSize = self.text.size(withAttributes: fontAttrs)
let rect = CGRect(x: CGFloat((width / 2.0) - (stringSize.width/2.0)),
                  y: CGFloat((height / 2.0) - (stringSize.height/2.0)),
                  width: CGFloat(stringSize.width),
                  height: CGFloat(stringSize.height))

let renderer = UIGraphicsImageRenderer(size: CGSize(width: CGFloat(width), height: CGFloat(height)))
let image = renderer.image { context in

    let color = UIColor.blue.withAlphaComponent(CGFloat(0.5))

    color.setFill()
    context.fill(rect)

    text.draw(with: rect, options: .usesLineFragmentOrigin, attributes: fontAttrs, context: nil)
}

let plane = SCNPlane(width: CGFloat(0.1), height: CGFloat(0.1))
plane.firstMaterial?.diffuse.contents = image

let node = SCNNode(geometry: plane)

编辑: 我添加了这些行:

let color = UIColor.blue.withAlphaComponent(CGFloat(0.5))

color.setFill()
context.fill(rect)

这可以让您设置背景颜色和不透明度。还有其他方法可以做到这一点 - 也可以让您绘制复杂的形状 - 但这是最​​简单的基本颜色。

编辑 2:添加了对 stringSizerect 的引用

【讨论】:

  • 非常感谢!它工作正常!你知道,我怎样才能改变背景颜色和不透明度?
  • 是的 - 我刚刚添加了绘制背景颜色所需的三行代码。
  • 嘿,你的代码是从哪里得到rect 变量的?
  • @Cesare 我现在添加了这个。 rect 是您要在图像中绘制的边界框。 x, y 是左上角。
  • @Jordan 谢谢,这段代码没有显示任何内容。
【解决方案3】:

实现这一目标的最简单(尽管未记录)方法是将由视图控制器支持的UIView 设置为SCNPlane(或任何其他几何体上的材质的漫反射内容,但它最适用于平面明显的原因)。

let plane = SCNPlane()
plane.firstMaterial?.diffuse.contents = someViewController.view
let planeNode = SCNNode(geometry: plane)

您必须将视图控制器保存在某个地方,否则它将被释放并且平面将不可见。仅使用 UIView 而不使用任何 UIViewController 将引发错误。

它最好的一点是它保留了所有的手势并且实际上就像一个简单的视图一样工作。例如,如果您使用UITableViewController 的视图,您将能够在场景中直接滚动它。

我还没有在 iOS 10 及更低版本上测试过它,但到目前为止它一直在 iOS 11 上运行。既适用于普通的 SceneKit 场景,也适用于 ARKit。

【讨论】:

  • 不知道。我得试试这个
  • 如果我调用 secondView 我只会得到一个白屏,我在上面发布了我的 secondViewController 的代码。
  • @Informatics 你不应该在viewDidLoad() 中重新分配self.view。如果您从情节提要中实例化 InformationViewController 并且那里有 secondView,则 view 将包含它。
  • 好的,我改了,但我有问题,我只得到一个没有内容的白屏。
  • 这对我有用!太感谢了!顺便说一句,我也遇到了只看到一个白色平面的问题,但那是因为我没有在任何地方存储对视图控制器的引用。我在主视图控制器中声明了一个变量来保持对辅助视图控制器的引用,现在它可以工作了,它甚至可以滚动(我使用表视图控制器来测试交互)。
猜你喜欢
  • 2018-12-09
  • 2019-06-17
  • 2019-03-20
  • 2023-03-03
  • 2018-12-06
  • 2020-09-05
  • 1970-01-01
  • 2019-06-19
  • 2018-08-26
相关资源
最近更新 更多