在Swift中不断更新UILabel

时间:2018-08-15 19:47:07

标签: ios swift arkit

我正在创建一个应用程序,该应用程序将在检测到图像后不断更新平面节点的坐标。但是,我想知道我将如何做。我的代码如下:

extension ViewController: ARSCNViewDelegate {

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        DispatchQueue.main.async {
            guard let imageAnchor = anchor as? ARImageAnchor,
                var imageName = imageAnchor.referenceImage.name  else { return }

            let planeNode = self.getPlaneNode(withReferenceImage: imageAnchor.referenceImage)
            planeNode.opacity = 1.0
            planeNode.eulerAngles.x = -.pi / 2
            planeNode.runAction(self.fadeAction)
            node.addChildNode(planeNode)

            let nodeCam = self.sceneView.session.currentFrame!.camera
            let cameraTransform = nodeCam.transform
            planeNode.position.x = cameraTransform.columns.3.x + 1
            planeNode.position.y = cameraTransform.columns.3.y + 1


            if imageName == "sample" {
                self.imageOne.text = "\"\(imageName)\""
                self.instructions.text = "IMAGE DETECTED: \"\(imageName)\""
                self.coordinateView.isHidden = false
                self.updateOne.isHidden = false
                self.coordinateX.text = "X: " + String(planeNode.position.x)
                self.coordinateY.text = "Y: " + String(planeNode.position.y)
            }

我要如何使当平面节点移动时与X坐标和Y坐标相对应的标签不断变化和更新?我尝试过重复循环,其中:

repeat {
   self.coordinateX.text = "X: " + String(planeNode.position.x)
   self.coordinateY.text = "Y: " + String(planeNode.position.y)
} while imageName == "sample" 

但这只会导致代码在检测到图像时冻结。有什么建议么?

2 个答案:

答案 0 :(得分:0)

这里有两个选项;您可以设置一个DispatchSource来注册计划的事件并建立处理程序。该处理程序可以是将点设置到标签中的函数。示例:

YDKJS book series

如果您认为数据会在短时间内大量更新/更改,那么此方法非常有用。

如果您认为这种情况不会发生,那么我将使用“ didSet”来监视变量并在“ didSet”函数中设置该函数。

答案 1 :(得分:0)

让我们说我有一个ARReferenceImage,叫做BlackMirrorz

在以下ARSCNViewDelegate中。方法,当检测到ARReferenceImage时,我正在加载模型:

//-------------------------
//MARK: - ARSCNViewDelegate
//-------------------------

extension ViewController: ARSCNViewDelegate{

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        //1. Check We Have A Valid Image Anchor
        guard let imageAnchor = anchor as? ARImageAnchor else { return }

        //2. Get The Detected Reference Image
        let referenceImage = imageAnchor.referenceImage

        //3. Load Our Model Only If Our Reference Image Name Is Valid & The Model Hasnt Already Been Placed
        if let matchedTargetImageName = referenceImage.name, matchedTargetImageName == "BlackMirrorz" && !modelPlaced {

            //a. Set Our Model To The Size Of The ReferenceImage
            let model = SCNNode(geometry: SCNPlane(width: referenceImage.physicalSize.width, height: referenceImage.physicalSize.height))

            //b. Rotate It
            model.eulerAngles.x = -.pi/2

            //c. Add It To Our Node
            node.addChildNode(model)

            //d. Name Our Node
            node.name = matchedTargetImageName

        }
    }
}

最重要的是代码的最后一行;我在其中为ARImageAnchor's节点提供了名称,这将使我们以后可以轻松跟踪。

已经加载了我们的模型,然后我们可以使用以下ARSessionDelegate方法:

func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { }

简单地说:

  

告诉代表该会话已调整其中一个的属性   或更多锚点。

因此,很容易使用您的Labels的当前坐标来更新任何SCNText'sARImageAnchor等,

//--------------------------
//MARK: -  ARSessionDelegate
//--------------------------

extension ViewController: ARSessionDelegate{

    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {

        //1. Enumerate Through Our Current ARAnchors
        for anchor in anchors{

            //2. If We Have An ARImageAnchor Then Get The Corresponding Node & Check That It's Name Is The One We Want To Track
            if let imageAnchor = anchor as? ARImageAnchor,
                let targetNode = self.augmentedRealityView.node(for: imageAnchor), targetNode.name == "BlackMirrorz"{

                //3. Get The Transform For The Anchor And Log This To The Console Or Update Your Labels
                print("""
                    Current Position X Of Anchor = \(imageAnchor.transform.columns.3.x)
                    Current Position Y Of Anchor = \(imageAnchor.transform.columns.3.y)
                    Current Position Z Of Anchor = \(imageAnchor.transform.columns.3.z)
                    """)
            }
        }
    }
}

希望它会为您指明正确的方向...