我有一个导航控制器,其中包含一个包含单个UIButton的根视图控制器。轻击按钮会将另一个视图控制器推入堆栈。第二个视图控制器包含一个ARKit SceneView(ARSCNView)。在场景内部,我使用SCNPlane添加一个节点,并设置平面材质的漫反射内容以使用由视图控制器支持的视图,如下所示:
import UIKit
import SceneKit
import ARKit
class SceneViewController: UIViewController {
@IBOutlet weak var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
}
func setupScene() {
sceneView.scene = SCNScene()
let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
// add a small plane at the origin...
let plane = SCNPlane(width: 0.1, height: 0.1)
// create a view controller, and add use its view as the plane's material contents...
let vc = UIViewController()
vc.view.backgroundColor = UIColor.red
plane.firstMaterial?.diffuse.contents = vc.view
let node = SCNNode(geometry: plane)
sceneView.scene.rootNode.addChildNode(node)
}
}
当我弹出此视图控制器(使用“后退”按钮或平移手势)时,根视图控制器停止响应触摸事件。
将设备旋转到横向,然后再回到纵向,似乎可以释放导致这种行为的任何原因
我已经尝试覆盖根视图控制器上的touchesBegan,但是不会被触发。
我试图强迫窗口成为第一响应者。
我已经确保SceneViewController被销毁,并且在视图控制器被销毁后,sceneView的会话仍未运行。
使用UIView或从内容视图控制器的视图生成的UIImage时不会发生此问题,但这意味着它无法与之交互。
这里是示例项目的链接。它需要在支持ARKit的设备上运行:https://github.com/duncanlowrie/vc-node-test
答案 0 :(得分:0)
我遇到了同样的问题。事实证明,如果将SKScene分配给plane.firstMaterial?.diffuse.contents,此行为就消失了,但是出于明显的原因,您需要UIView(我也是如此)。
此外,我认为只有三分之二的屏幕无法响应。我在iPhone 7和iPhone XS上进行了尝试,如果您尝试与屏幕底部三分之一处的内容进行交互,则应该可以使用。丑虫。
还尝试使用情节提要中的新入口点来重新实例化AppDelegate窗口的rootViewController:不高兴。
答案 1 :(得分:0)
/* I think whenever UIView are directly attached to SCNMaterial and
that SCNMaterial to SCNNode. SCNMaterial are still being used when
previous screen is visited. By resetting ARSCNView seems to resolve the
issue. */
import UIKit
import ARKit
class SceneViewController: UIViewController {
@IBOutlet weak var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
//do not set setupScene function here
}
override func viewWillAppear(_ animated: Bool) {
super.viewDidLoad()
//set setupScene function here
setupScene()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//reset ARSCNView before going back to previous screen
self.sceneView = ARSCNView()
}
func setupScene() {
sceneView.scene = SCNScene()
let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
// add a small plane at the origin...
let plane = SCNPlane(width: 0.1, height: 0.1)
// create a view controller, and add use its view as the plane's material contents...
let vc = UIViewController()
vc.view.backgroundColor = UIColor.red
plane.firstMaterial?.diffuse.contents = vc.view
let node = SCNNode(geometry: plane)
sceneView.scene.rootNode.addChildNode(node)
}
}