代码之家  ›  专栏  ›  技术社区  ›  Lance Samaria

快速访问UIApplication.shared.statusBarOrientation状态从主线程

  •  0
  • Lance Samaria  · 技术社区  · 5 年前

    我正试图进入 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 对象访问此行的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
        }
    }
    

    enter image description here

    0 回复  |  直到 5 年前
        1
  •  0
  •   Shehata Gamal    5 年前

    在主线程中调度使其他代码成为值 var videoOrientation: AVCaptureVideoOrientation! 成为 nil 当你在切换前返回时,最好确定你调用了整个 startRecording() 从主线程开始

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

    DispatchQueue.main.async