【问题标题】:Segue to controller takes 5-10 seconds to displaySegue 到控制器需要 5-10 秒才能显示
【发布时间】:2018-06-10 00:27:41
【问题描述】:

我正在使用 swift 4 并且有一个应用程序,人们可以通过我的应用程序打开他们的手机摄像头。我有一个名为CameraController 的ViewController,它具有默认的UIView,并且我有一个名为CameraView 的视图,它在其上显示用户相机和其他按钮。

当我单击其中一个按钮时,它会通过 segue (PlacesController) 将我带到另一个视图控制器。当我关闭PlacesController 时,我会返回CameraController,但是子视图现在需要大约 8 或 10 秒才能再次显示。

有没有什么方法可以在保持当前子视图的同时转到另一个控制器

同样的问题是,当我转到我的 segue 控制器 PlaceController 然后再回到我的 CameraController 时,相机和子层变得可见大约需要 8 或 10 秒。特别是下面的这段代码,我想知道是否可以让我的子层继续运行,因为等待 10 秒才能显示太多。

self.CameraView.layer.insertSublayer(previewLayer!, at: 0)

这是我的代码:

class CameraController: UIViewController {
    @IBOutlet weak var CameraView: UIView!
     var previewLayer: AVCaptureVideoPreviewLayer?
     let captureSession = AVCaptureSession()


  override func viewDidLoad() {
        super.viewDidLoad()


    }
 override func viewDidAppear(_ animated: Bool) {
           DispatchQueue.main.async {
             self.beginSession()
        }

    func beginSession() {
   // gets the camera showing and displays buttons on top of it
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.CameraView.layer.insertSublayer(previewLayer!, at: 0)
        previewLayer?.frame = self.CameraView.layer.bounds

        previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        captureSession.startRunning()
        stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecType.jpeg]
        if captureSession.canAddOutput(stillImageOutput) {
            captureSession.addOutput(stillImageOutput)
        }
    }


  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "PlacesController" {
            let PlaceAreaSearchC: ColorC = segue.destination as! PlacesController
            PlaceAreaSearchC.delegate = self
        }
    }

 // PlacesController
class PlacesController: UIViewController {
    @IBAction func backAction(_ sender: Any) {
   // This is how I go back to my view CameraController
         dismiss(animated: true, completion: nil)
    }
 }

【问题讨论】:

  • 使用 Instruments 尝试缩小您的问题范围。
  • 为您的 beginSession 使用不同的线程怎么样?您现在正在做的是在主 GUI 线程上运行它(...您对当前 IMPL 所做的只是将其移动到主队列的末尾,但它仍在 GUI 的队列中)。如果你尝试这个会发生什么?

标签: ios swift camera segue avcapturesession


【解决方案1】:

AVCaptureSession startRunning 调用阻塞了你的主线程,因此延迟。

正如startRunning()’s Apple Doc 所说:

startRunning() 方法是一个阻塞调用,可能需要一些时间, 因此,您应该在串行队列上执行会话设置,以便 主队列未被阻塞(保持 UI 响应)。

【讨论】:

  • 很高兴看到工作代码示例将该调用包装在主线程以外的其他地方,这将使这个答案成为规范。
  • @DimaTisnek 在下面查看我的答案
【解决方案2】:

除了 Lyndsey Scottanswer

    let backCamera: AVCaptureDevice? = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: AVMediaType.video, position: AVCaptureDevice.Position.back)

    guard let camera = backCamera, let deviceInput = try? AVCaptureDeviceInput(device: camera) else {
        self?.didReceive(captureSession: nil)
        return
    }

    DispatchQueue.global(qos: .userInitiated).async { [weak self] in
        let deviceOutput = AVCapturePhotoOutput()
        let cameraSession = AVCaptureSession()

        cameraSession.beginConfiguration()
        cameraSession.sessionPreset = .low
        if cameraSession.canAddInput(deviceInput) {
            cameraSession.addInput(deviceInput)
        }
        if cameraSession.canAddOutput(deviceOutput) {
            cameraSession.addOutput(deviceOutput)
        }
        cameraSession.commitConfiguration()
        cameraSession.startRunning()
        DispatchQueue.main.async {
            self?.didReceive(captureSession: cameraSession)
        }
    }

Xcode 10.0、Swift 4.2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多