自iOS 8.0起,函数didRotateFromInterfaceOrientation
已弃用,我现在不知道如何正确更改AVCaptureVideoPreviewLayer的方向。
根据"interfaceOrientation" is deprecated in iOS 8, How to change this method Objective C,我有以下工作代码来根据AVCaptureVideoOrientation
获取statusBarOrientation
:
- (AVCaptureVideoOrientation)getOrientation {
// Translate the orientation
switch ([[UIApplication sharedApplication] statusBarOrientation]) {
case UIInterfaceOrientationPortrait:
return AVCaptureVideoOrientationPortrait;
case UIInterfaceOrientationPortraitUpsideDown:
return AVCaptureVideoOrientationPortraitUpsideDown;
case UIInterfaceOrientationLandscapeLeft:
return AVCaptureVideoOrientationLandscapeLeft;
case UIInterfaceOrientationLandscapeRight:
return AVCaptureVideoOrientationLandscapeRight;
default:
return AVCaptureVideoOrientationPortrait;
}
}
当方向改变时,我需要调用以下函数:
[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
但我不知道在哪里放置它。
由于didRotateFromInterfaceOrientation
已被弃用且Apple建议使用viewWillTransitionToSize:withTransitionCoordinator:
,因此尝试这似乎很自然:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
}];
}
但是如果正在呈现UIViewController
,则不会调用此函数(似乎是基于"viewWillTransitionToSize:" not called in iOS 9 when the view controller is presented modally的已知错误)。即使解决了这个问题,也存在另一个问题:方向更改 等同于大小更改。例如,如果视图显示UIModalPresentationFormSheet
如下,
SecondViewController *vc = [[SecondViewController alloc] init];
vc.view.backgroundColor = [UIColor greenColor];
vc.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:vc animated:true completion:nil];
在iPad的横向和纵向模式下,呈现的视图大小相同:
因此,我不能简单地使用viewWillTransitionToSize
。
我注意到UIDeviceOrientationDidChangeNotification
未被弃用。大!我尝试注册一个通知:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Some other code to set up the preview layer
// ...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
- (void)viewWillDisappear:(BOOL)animated
{
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)deviceOrientationDidChange:(NSNotification *)notification {
[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
}
几乎正在工作,它已经关闭了!问题是,当我获得设备方向更改通知时,可能会启动旋转视图的动画,也可能不会。换句话说,如果设备已经向上旋转但动画仍处于待处理状态,则返回值[[UIApplication sharedApplication] statusBarOrientation]
可能不正确。
我不知道还有什么可以尝试:(有什么想法吗?
答案 0 :(得分:2)
以下应该能够在swift 2.1中正确处理视频预览的方向:
import UIKit
import AVFoundation
class AgnesAudioViewController: UIViewController {
var audioPlayer = AVAudioPlayer()
var toggleState = 1
@IBOutlet var slider: UISlider!
@IBAction func done(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
@IBAction func play(sender: AnyObject) {
audioPlayer.play()
}
@IBAction func pause(sender: AnyObject) {
audioPlayer.pause()
}
@IBAction func stop(sender: AnyObject) {
audioPlayer.stop()
}
@IBAction func scrubAudio(sender: AnyObject) {
audioPlayer.stop()
audioPlayer.currentTime = NSTimeInterval(slider.value)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
@IBAction func playPauseButton(sender: AnyObject) {
var playBtn = sender as! UIButton
if toggleState == 1 {
audioPlayer.play()
toggleState = 2
playBtn.setImage(UIImage(named:"pause.png"),forState:UIControlState.Normal)
} else {
audioPlayer.pause()
toggleState = 1
playBtn.setImage(UIImage(named:"play.png"),forState:UIControlState.Normal)
}
}
override func viewDidLoad() {
super.viewDidLoad()
var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateSlider"), userInfo: nil, repeats: true)
slider.maximumValue = Float(audioPlayer.duration)
let pathString = NSBundle.mainBundle().pathForResource("agnes", ofType: "mp2")
if let pathString = pathString {
let pathURL = NSURL(fileURLWithPath: pathString)
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: pathURL)
} catch {
print("error")
}
}
}
func updateSlider() {
slider.value = Float(audioPlayer.currentTime)
}
}