我有一个奇怪的问题,或者也许我在做的事情很奇怪。
我有一个ARKit应用,当检测到条形码时,该应用会显示一个SCNNode,其中嵌入了数据视图。当点击数据视图时,我想将其与节点分离,并将其作为子视图添加到主视图中。再次点击时,我想将其重新连接到SCNNode。
我发现this code至少完成了我想要的部分。
我的应用程序第一次运行良好。数据出现在SCNNode中:
{
let transform = anchor.transform
let label = SimpleValueViewController(nibName: "SimpleValueViewController", bundle: nil)
let plane = SCNPlane(width: self.sceneView.bounds.width/2000, height: self.sceneView.bounds.height/2000/2) //was sceneView
label.update(dataItem.title!, andValue: dataItem.value!, withTrend: dataItem.trend)
label.delegate = self
plane.firstMaterial?.blendMode = .alpha
plane.firstMaterial?.diffuse.contents = label.view //self.contentController?.view
let planeNode = SCNNode(geometry: plane)
planeNode.opacity = 0.75
planeNode.simdPosition = float3(transform.columns.3.x + ( base * count), 0, transform.columns.3.z)
node.addChildNode(planeNode)
childControllers[label] = planeNode
label.myNode = planeNode
label.parentNode = node
if("Speed" == anchorLabels[anchor.identifier]!) {
let constraint = SCNBillboardConstraint()
planeNode.constraints = [constraint]
}
count += 1
}
SimpleValueViewController
具有一个点击识别器,可以在子视图和节点内部之间切换。
这是问题所在。
它很好。该视图位于节点内部。
点击时,它会附加到主视图。
再次点按该节点只会显示一个白色正方形,而点按不再有效。
我最终放弃了并重新创建了一个新的viewController,但偶尔还是会失败,只有一个白色正方形:
这是分离/附加的代码,因为我一直在研究它一段时间,所以很混乱:
func detach(_ vc:Detachable) {
if let controller = vc as? SimpleValueViewController {
controller.view.removeFromSuperview();
self.childControllers.removeValue(forKey: controller)
let node = controller.myNode
let parent = controller.parentNode
let newController = SimpleValueViewController(nibName: "SimpleValueViewController", bundle: nil)
if let v = newController.view {
print("View: \(v)")
newController.myNode = node
newController.parentNode = parent
newController.update(controller.titleString!, andValue: controller.valueString!, withTrend: controller.trendString!)
newController.delegate = self
newController.scaley = vc.scaley
newController.scalex = vc.scalex
newController.refreshView()
let plane = node?.geometry as! SCNPlane
plane.firstMaterial?.blendMode = .alpha
plane.firstMaterial?.diffuse.contents = v
// newController.viewWillAppear(false)
newController.parentNode?.addChildNode(newController.myNode!)
newController.attached = false;
self.childControllers[newController] = node
}
} else {
print("Not a know type of controller")
}
}
func attach(_ vc:Detachable) {
DispatchQueue.main.async {
if let controller = vc as? SimpleValueViewController {
self.childControllers.removeValue(forKey: controller)
let newController = SimpleValueViewController(nibName: "SimpleValueViewController", bundle: nil)
let node = controller.myNode
let parent = controller.parentNode
let scaleX = vc.scalex!/self.view.frame.size.width
let scaleY = vc.scaley!/self.view.frame.size.height
let scale = min(scaleX, scaleY)
let transform = CGAffineTransform(scaleX: scale, y: scale)
newController.view.transform = transform
newController.myNode = node
newController.parentNode = parent
newController.update(controller.titleString!, andValue: controller.valueString!, withTrend: controller.trendString!)
newController.delegate = self
newController.scaley = vc.scaley
newController.scalex = vc.scalex
node?.removeFromParentNode()
self.childControllers[newController] = node
newController.attached = true
self.view.addSubview(newController.view)
} else {
print("Not a know type of controller to attach")
}
}
}
我当时认为这是一个时序问题,因为从笔尖加载视图的工作很懒惰,所以我在SimpleValueViewController(nibName:“ SimpleValueViewController”,bundle:nil)之后进入睡眠状态1秒钟,但这没有帮助。
还有什么我可以尝试的吗?我离基地远吗?我希望不必在每次切换数据时都重新创建视图控制器。
谢谢。
渲染功能:
func renderer(_ renderer:SCNSceneRenderer,didAdd节点:SCNNode,锚点:ARAnchor){
// func renderer(_ renderer:SCNSceneRenderer,nodeFor锚点:ARAnchor)-> SCNNode? {
// updateQueue.async {
//Loop through the near and far data and add stuff
let data = "Speed" == anchorLabels[anchor.identifier]! ? nearData : farData
let base = "Speed" == anchorLabels[anchor.identifier]! ? 0.27 : 0.2 as Float
print ("Getting Node for: " + self.anchorLabels[anchor.identifier]!)
var count = 0.0 as Float
for dataItem in data {
let transform = anchor.transform
let label = SimpleValueViewController(nibName: "SimpleValueViewController", bundle: nil)
let plane = SCNPlane(width: self.sceneView.bounds.width/2000, height: self.sceneView.bounds.height/2000/2) //was sceneView
label.update(dataItem.title!, andValue: dataItem.value!, withTrend: dataItem.trend)
label.delegate = self
plane.firstMaterial?.blendMode = .alpha
plane.firstMaterial?.diffuse.contents = label.view //self.contentController?.view
let planeNode = SCNNode(geometry: plane)
planeNode.opacity = 0.75
planeNode.simdPosition = float3(transform.columns.3.x + ( base * count), 0, transform.columns.3.z)
node.addChildNode(planeNode)
childControllers[label] = planeNode
label.myNode = planeNode
label.parentNode = node
if("Speed" == anchorLabels[anchor.identifier]!) {
let constraint = SCNBillboardConstraint()
planeNode.constraints = [constraint]
}
count+=1
}
并更新
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
guard currentBuffer == nil else {
return
}
self.updateFocusSquare(isObjectVisible: false)
// Retain the image buffer for Vision processing.
self.currentBuffer = sceneView.session.currentFrame?.capturedImage
classifyCurrentImage()
}
ClassifyCurrentImage是条形码识别器所在的位置。如果找到条形码,它将在场景中的位置添加锚点。