【问题标题】:RemoveFromSuperview doesn't seemed to remove the subview i createdRemoveFromSuperview 似乎没有删除我创建的子视图
【发布时间】:2015-10-20 21:26:50
【问题描述】:

我正在使用 swift 代码进行测试以制作 QR 码扫描仪,但我无法在重置时移除红框。

我在 viewDidLoad 中有以下代码

// Red box highlight
    qrCodeFrameView.layer.borderColor = UIColor.redColor().CGColor
    qrCodeFrameView.layer.borderWidth = 2
    viewForLayer.addSubview(qrCodeFrameView)
    viewForLayer.bringSubviewToFront(qrCodeFrameView)
    // End box highlight

现在扫描 QR 时会显示边框:

let barCodeObject = self.previewLayer?.transformedMetadataObjectForMetadataObject(metadataObject as! AVMetadataMachineReadableCodeObject) as!  AVMetadataMachineReadableCodeObject
        qrCodeFrameView.frame = barCodeObject.bounds

我喜欢使用重置按钮移除边框并能够重新扫描。使用以下内容我可以重新扫描,但最后一个红色矩形仍然可见

        @IBAction func resetButtonTapped(sender: AnyObject) {
        self.refreshView()
    }

    func refreshView(){
        //remove frame border
        qrCodeFrameView.removeFromSuperview()
        self.viewDidLoad()   
self.viewWillAppear(true)
    }

我在 qrCodeFrameView.removeFromSuperview() 处添加了一个断点,它停在那里,但我不完全知道要寻找什么。 (我的意思是我得到了变量,但对于 removeFromSuperview 我不知道会发生什么??)

问候

[编辑] 好的,我按照提示从不直接调用 viewDidLoad 和 viewDidAppear,我创建了一个单独的函数 cameraLayerWithBorder(),但在 reset/refreshView 上仍然显示红色边框?

 func cameraLayerWithBorder(){
        view.backgroundColor = UIColor.blackColor()
        captureSession = AVCaptureSession()

        let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        let videoInput: AVCaptureDeviceInput

//capture image code .......

        // Previewlayer with camera added to a placed layer 
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
        previewLayer.frame = viewForLayer.bounds;
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        viewForLayer.layer.addSublayer(previewLayer);


        // Red box highlight
        qrCodeFrameView.layer.borderColor = UIColor.redColor().CGColor
        qrCodeFrameView.layer.borderWidth = 2
        viewForLayer.addSubview(qrCodeFrameView)
        viewForLayer.bringSubviewToFront(qrCodeFrameView)
        // End box highlight

         captureSession.startRunning();
    }

我编辑了 refreshView()

        func refreshView(){
        print("reset")
        //remove frame border
        qrCodeFrameView.removeFromSuperview()
       // self.viewDidLoad()
//        self.viewWillAppear(true)
        self.cameraLayerWithBorder()
    }

这个函数的一部分设置了红色边框

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
    captureSession.stopRunning()

    if let metadataObject = metadataObjects.first {//fula says let verwijderen
        let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;

        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        // add red borders
        let barCodeObject = self.previewLayer?.transformedMetadataObjectForMetadataObject(metadataObject as! AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
        qrCodeFrameView.frame = barCodeObject.bounds
        // end add red borders
        foundCode(readableObject.stringValue);
    }

    dismissViewControllerAnimated(true, completion: nil)
}

这里是debug中的视图截图(红色边框是UIWindow > UIView > UIView > UIView

[编辑 2] 可行的解决方案,多亏了 Ibrahim,我忽略了显而易见的问题,我不得不将函数 cameraLayerWithBorder 中的 frameborder 代码部分添加到 captureOutput 函数

 // Red box highlight

        qrCodeFrameView.layer.borderColor = UIColor.redColor().CGColor
        qrCodeFrameView.layer.borderWidth = 2
        viewForLayer.addSubview(qrCodeFrameView)
        viewForLayer.bringSubviewToFront(qrCodeFrameView)
        // End box highlight

还是不知道是不是这样

【问题讨论】:

  • 永远不要自己打电话给viewDidLoadviewWillAppear
  • tx,我已经将两者都注释掉了,并使用我最初在 viewDidLoad() 中的代码添加了一个函数

标签: ios swift qr-code


【解决方案1】:

仅从 superview 中删除是行不通的,您还需要删除预览层。请在下面尝试,希望它会起作用。

videoPreviewLayer?.removeFromSuperlayer()
view.sendSubview(toBack: self.qrCodeFrameView!)
self.qrCodeFrameView?.removeFromSuperview()
captureSession?.stopRunning()

如果这不起作用,请告诉我。

【讨论】:

    【解决方案2】:

    在处理 UI 操作时,您必须使用 main queue

    目标 C

    dispatch_async(dispatch_get_main_queue(),^{
        [qrCodeFrameView removeFromSuperview]
     })
    

    斯威夫特

    dispatch_async(dispatch_get_main_queue()) {
        qrCodeFrameView.removeFromSuperview()
    }
    

    【讨论】:

    • 这不是必需的。这一切都已经在主线程上完成了。
    • 答案是正确的,如果您正在处理服务器请求,则必须在主队列中执行此操作。 SWIFT 4 DispatchQueue.main.async { self.XXX.removeFromSuperview() }
    【解决方案3】:

    您从resetButtonTapped() 中的父视图中删除该视图,但之后调用函数cameraLayerWithBorder()。在该方法中,您再次添加qrCodeFrameView

    不要调用cameraLayerWithBorder()afterwards,而是在resetButtonTapped() 中编写你想做的新代码,或者创建一个新方法并在你删除它之后调用它。

    --- 第一个答案---

    尝试删除viewDidLoad() & viewWillAppear(),我认为这是原因。不是100%确定。但在这种情况下你不必调用那些方法,但如果你想调用viewDidLoad 使用这种方法

    https://stackoverflow.com/a/9868106/1842694

    【讨论】:

    • 嗨易卜拉欣,我已经用代码添加了功能(见我的编辑)但仍然显示边框
    • 嗯,但是 cameraLayerWithBorder() 有我喜欢执行的代码。将其视为一种初始状态,在扫描代码后,我想回到第一个状态,因此我认为我可以重用代码。但我明白你的意思
    • 嗯,所以您仍然希望在单击重置时显示qrCodeFrameView,但只是没有红色边框?你能说得更具体些吗
    猜你喜欢
    • 2021-02-06
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多