【问题标题】:Swift -access UIApplication.shared.statusBarOrientation from main threadSwift - 从主线程访问 UIApplication.shared.statusBarOrientation
【发布时间】:2019-12-14 12:36:47
【问题描述】:

我正在尝试访问UIApplication.shared.statusBarOrientation,但我不断收到错误UIApplication.statusBarOrientation() must be used from main thread only

我尝试将它和使用它的 switch 语句添加到 mainQueue 中,但这会导致 return value 从它包含的函数中以 nil 值崩溃:

DispatchQueue.main.async {

    let interfaceOrientation = UIApplication.shared.statusBarOrientation

    switch interfaceOrientation {

    case .portrait, .portraitUpsideDown, .unknown:
        videoOrientation = .portrait
    case .landscapeLeft:
        videoOrientation = .landscapeRight
    case .landscapeRight:
        videoOrientation = .landscapeLeft
    @unknown default:
        break
    }
}

代码:

func videoOrientation() -> AVCaptureVideoOrientation {

    var videoOrientation: AVCaptureVideoOrientation!

    let orientation: UIDeviceOrientation = UIDevice.current.orientation

    switch orientation {

    case .faceUp, .faceDown, .unknown:

        // ** I tried to add this alone to the mainQueue but the switch statement couldn't access it so then I tried to add the entire switch but that lead to the return value crashing with a nil
        let interfaceOrientation = UIApplication.shared.statusBarOrientation

        switch interfaceOrientation {

        case .portrait, .portraitUpsideDown, .unknown:
            videoOrientation = .portrait
        case .landscapeLeft:
            videoOrientation = .landscapeRight
        case .landscapeRight:
            videoOrientation = .landscapeLeft
        @unknown default:
            break
        }

    case .portrait, .portraitUpsideDown:
        videoOrientation = .portrait
    case .landscapeLeft:
        videoOrientation = .landscapeRight
    case .landscapeRight:
        videoOrientation = .landscapeLeft
    @unknown default:
        break
    }

    return videoOrientation // ** crashes here **
}

我在按下camerButton 使用AVFoundation 录制视频时访问返回值。 movieFileOutput对象在movieFileOutput.connection(with: AVMediaType.video)?.videoOrientation = videoOrientation()这一行访问videoOrientation:

代码:

let captureSession = AVCaptureSession()
var movieFileOutput = AVCaptureMovieFileOutput()
var videoFileUrlFromCamera: URL?

func startRecording() {

    if !captureSession.outputs.contains(movieFileOutput) {
        return
    }

    // Stop recording
    if movieFileOutput.isRecording {

        stopMovieRecordigShowControls()

    } else {

        if !captureSession.outputs.contains(movieFileOutput) {
            return
        }

        // Start recording
        movieFileOutput.connection(with: AVMediaType.video)?.videoOrientation = videoOrientation()

        movieFileOutput.maxRecordedDuration = maxRecordDuration()

        videoFileUrlFromCamera = URL(fileURLWithPath: videoFileLocation())

        if let videoFileUrlFromCamera = videoFileUrlFromCamera {

            movieFileOutput.startRecording(to: videoFileUrlFromCamera, recordingDelegate: self)
        }

    }
}

我该如何解决这个问题?

更新 我还尝试将整个代码包装在 DispatchQueue 中,但出现Cannot return expression of type () to return type AVCaptureVideoOrientation 的编译错误:

func videoOrientation() -> AVCaptureVideoOrientation {

    DispatchQueue.main.async {

        var videoOrientation: AVCaptureVideoOrientation!

        let orientation: UIDeviceOrientation = UIDevice.current.orientation

        switch orientation {

        case .faceUp, .faceDown, .unknown:

            let interfaceOrientation = UIApplication.shared.statusBarOrientation

            switch interfaceOrientation {

            case .portrait, .portraitUpsideDown, .unknown:
                videoOrientation = .portrait
            case .landscapeLeft:
                videoOrientation = .landscapeRight
            case .landscapeRight:
                videoOrientation = .landscapeLeft
            @unknown default:
                break
            }
            break
        case .portrait, .portraitUpsideDown:
            videoOrientation = .portrait
        case .landscapeLeft:
            videoOrientation = .landscapeRight
        case .landscapeRight:
            videoOrientation = .landscapeLeft
        @unknown default:
            break
        }

        return videoOrientation
    }
}

【问题讨论】:

  • 您的变量名和函数名相同videoOrientation 可能是问题...并在函数外部声明该变量以使其可访问
  • 您好,我试图在它仍然说需要从主线程调用的函数之外访问它

标签: ios swift statusbar dispatch-queue


【解决方案1】:

在主线程中调度其他代码会使 var videoOrientation: AVCaptureVideoOrientation! 的值在您返回它时成为nil,因为在 switch 之前返回触发,最好确保从主线程调用整个 startRecording(),例如

DispatchQueue.main.async {
    self.startRecording()
}

由于权限检查的关闭在后台线程中运行,因此您需要在DispatchQueue.main.async 内调度录制的调用

【讨论】:

  • 嗨,我实际上尝试过,但出现了另一个问题。它说“无法返回类型 () 的表达式以返回类型 AVCaptureVideoOrientation”。将所有内容包装在 DispatchQueue.main.async 中的整个函数中
  • 我添加了使用它的代码。它在 startRecording() 函数中
  • 你在哪里打电话startRecording
  • 这是一个按钮,调用它。一旦按下相机按钮,它就会调用该函数。我在那里进行了一些其他检查以确保授予用户权限,如果是,则调用 startRecording() 函数。
  • 这就是权限检查的关闭在后台线程中运行的原因,将该函数包装在 DispatchQueue.main.async {
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多