首页 > 解决方案 > Swift - 从主线程访问 UIApplication.shared.statusBarOrientation

问题描述

我正在尝试访问,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对象访问该行上的 videoOrientation movieFileOutput.connection(with: AVMediaType.video)?.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
    }
}

在此处输入图像描述

标签: iosswiftstatusbardispatch-queue

解决方案


在主线程中调度其他代码使得当你返回它时返回它的值 var videoOrientation: AVCaptureVideoOrientation!nilswitch 之前触发,最好确保你startRecording()从主线程调用整个

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

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


推荐阅读