ios - Swift - 从主线程访问 UIApplication.shared.statusBarOrientation

标签 ios swift statusbar dispatch-queue

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

enter image description here

我尝试将它和使用它的 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
    }
}

enter image description here

最佳答案

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

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

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

关于ios - Swift - 从主线程访问 UIApplication.shared.statusBarOrientation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59335158/

相关文章:

swift - 四舍五入到两位小数

bash - bash 中的状态栏

ios - 无法识别的选择器导致的 NSInvalidArgumentFormatException 已发送至发件人 : while trying to print tag of a UILabel

ios - 滚动时收缩的标题 View

ios - 新的访问 token 。即使我替换了 session_key 和 sig,也始终无法进行身份验证

ios - Swift 单元测试 IBAction

swift - 新分配的对象之前可以在 Swift 中使用过 ObjectIdentifier 吗?

ios - Swift 框架或 Objective-c 库

ios - 即使使用 UIModalPresentationOverFullScreen 也更改 UIStatusbarStyle

statusbar - 如何在 byobu 中更改 "activity in window"颜色