Ios ARKit:如何将UIView添加到ARKit场景?
我正在使用ARKit进行AR项目 我想向ARKit场景添加UIView。当我点击一个对象时,我想以对象旁边的“弹出窗口”的形式获取信息。此信息位于UIView中 是否可以将此UIView添加到ARKit场景? 我将此UIView设置为场景,然后我可以做什么? 我可以给它一个节点,然后将其添加到ARKit场景中吗?如果是,它是如何工作的 还是有别的办法 谢谢大家! 编辑:我的第二个ViewController的代码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
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谢谢,我这边的代码没有显示任何内容。