Ios ARKit:如何将UIView添加到ARKit场景?

Ios ARKit:如何将UIView添加到ARKit场景?,ios,iphone,swift,uiview,arkit,Ios,Iphone,Swift,Uiview,Arkit,我正在使用ARKit进行AR项目 我想向ARKit场景添加UIView。当我点击一个对象时,我想以对象旁边的“弹出窗口”的形式获取信息。此信息位于UIView中 是否可以将此UIView添加到ARKit场景? 我将此UIView设置为场景,然后我可以做什么? 我可以给它一个节点,然后将其添加到ARKit场景中吗?如果是,它是如何工作的 还是有别的办法 谢谢大家! 编辑:我的第二个ViewController的代码 class InformationViewController: UIViewCo

我正在使用ARKit进行AR项目

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

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

还是有别的办法

谢谢大家!

编辑:我的第二个ViewController的代码

class InformationViewController: UIViewController {

    @IBOutlet weak var secondView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = secondView
    }
}
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)
编辑2:firstViewController中的代码

class InformationViewController: UIViewController {

    @IBOutlet weak var secondView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = secondView
    }
}
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)

我只能看到飞机的白色屏幕,而不是视图。

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

  • 创建一个
    SCNPlane
  • 使用所需的所有元素创建
    ui视图
  • UIView
    创建图像上下文
  • 将此图像用作
    SCNPlane
    的材质

  • 或者更容易使用标签制作
    SKScene
    ,并将其添加为
    SCNPlane
    的材质

    要在世界上的标签中放置文本,请将其绘制到图像中,然后将该图像附加到
    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:添加了对
    stringSize
    rect

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

    您必须将视图控制器保留在某个位置,否则它将被释放,平面将不可见。只使用
    UIView
    而不使用任何
    UIViewController
    将抛出错误

    它最棒的地方在于它保留了所有的手势,实际上就像一个简单的视图一样工作。例如,如果使用
    UITableViewController
    的视图,您将能够在场景中滚动它



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

    您的意思是希望在真实世界中以3D显示信息吗?或者你想让信息通过一个segue显示到另一个视图控制器?我想把它放在现实世界中的3D中。正如上面Lësha所说,在iOS 12.1.x之前,它一直工作得很好,如果你需要关闭在SCNPlane中显示UIView的UIViewController,结果会怎样,屏幕顶部三分之二的区域将对触地事件无响应。今天早些时候提交了此错误。@TeodorIuliuRadu您同时发现了更多信息吗?我是12.2测试版,识别器对我来说根本不起作用。谢谢!如何从UIView创建图像上下文?很抱歉,我现在无法提供任何信息。您可以在StackOverflow上找到从uiview轻松创建图像的方法,非常感谢!我的问题是现在我不能称之为视图。它与ViewController不兼容。您使用/观看过twitter ar应用程序吗?这个方法很相似(我就是这么想的)。可以仅将UIView显示为平面的材质。并将其他节点(平面)作为按钮。您可以通过点击用作按钮的节点来更改UIView的元素,并更改平面的材质。我认为Lësha Turkowski的方法正是您所需要的。我不知道。我必须尝试一下如果我调用secondView我只得到一个白色屏幕,我在上面发布了secondView控制器的代码。@Informatics您不应该在
    viewDidLoad()中重新分配
    self.view
    。如果您从故事板实例化
    InformationViewController
    ,并且它有
    secondView
    在那里,那么
    视图将包含它。好的,我更改了它,但我有一个问题,我只得到一个没有内容的白色屏幕。这对我很有效!非常感谢你!顺便说一句,我也有只看到白色平面的问题,但那是因为我没有在任何地方存储对视图控制器的引用。我在主视图控制器中声明了一个变量以保留对次视图控制器的引用,现在它工作了,甚至可以滚动(我使用了一个表视图控制器来测试交互)。非常感谢!它很好用!!!你知道,我如何改变背景色和不透明度吗?是的,我刚刚添加了绘制背景色所需的三行。嘿,你的代码从哪里获得
    rect
    变量?我现在添加了这个。
    rect
    是要在图像中绘制的边界框
    x
    y
    在左上角。@Jordan谢谢,我这边的代码没有显示任何内容。