作者:黛滢陌陌乄 | 来源:互联网 | 2023-05-20 19:06
我创建了一个AVPlayerViewController
和一个附加AVPlayer
在viewDidAppear
一个自定义的方法UIViewController
.但是,当我按下"完成"按钮时,我的自定义视图控制器会自动关闭.
我想拦截这个动作,以便使用我自己的放松塞格,但我不知道该怎么做.我找到了MPMoviePlayerViewController
但不是的例子AVPlayerViewController
.
我找到的代码MPMoviePlayerViewController
如下:
- (void)playVideo:(NSString *)aVideoUrl {
// Initialize the movie player view controller with a video URL string
MPMoviePlayerViewController *playerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:aVideoUrl]] autorelease];
// Remove the movie player view controller from the "playback did finish" notification observers
[[NSNotificationCenter defaultCenter] removeObserver:playerVC
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerVC.moviePlayer];
// Register this class as an observer instead
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerVC.moviePlayer];
// Set the modal transition style of your choice
playerVC.modalTransitiOnStyle= UIModalTransitionStyleCrossDissolve;
// Present the movie player view controller
[self presentModalViewController:playerVC animated:YES];
// Start playback
[playerVC.moviePlayer prepareToPlay];
[playerVC.moviePlayer play];
}
- (void)movieFinishedCallback:(NSNotification *)aNotification {
// Obtain the reason why the movie playback finished
NSNumber *finishReason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
// Dismiss the view controller ONLY when the reason is not "playback ended"
if ([finishReason intValue] != MPMovieFinishReasonPlaybackEnded) {
MPMoviePlayerController *moviePlayer = [aNotification object];
// Remove this class from the observers
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
// Dismiss the view controller
[self dismissModalViewControllerAnimated:YES];
}
}
我向Apple询问了这个问题,他们回复如下:
感谢您与Apple开发人员技术支持(DTS)联系.我们的工程师已经审核了您的请求,并得出结论,鉴于当前出货的系统配置,没有支持的方法来实现所需的功能.
dev..
5
我将AVPlayerViewController子类化,并发布了来自viewWillDisappear的通知,以指示解雇AVPlayerViewController.
- (void) viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] postNotificationName:kPlayerViewDismissedNotification object:nil];
[super viewWillDisappear:animated];
}
这可能不是100%正确(因为如果你有另一个视图显示在AVPlayerViewController上会失败),但它对我有用,因为AVPlayerViewController总是在堆栈的顶部.
1> dev..:
我将AVPlayerViewController子类化,并发布了来自viewWillDisappear的通知,以指示解雇AVPlayerViewController.
- (void) viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] postNotificationName:kPlayerViewDismissedNotification object:nil];
[super viewWillDisappear:animated];
}
这可能不是100%正确(因为如果你有另一个视图显示在AVPlayerViewController上会失败),但它对我有用,因为AVPlayerViewController总是在堆栈的顶部.
根据Apple Docs:**不要继承AVPlayerViewController.覆盖此类的方法不受支持并导致未定义的行为.**来源:https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVPlayerViewController_Class/
如果我不想继承AVPlayerViewController(如Apple建议:不要继承AVPlayerViewController.覆盖此类的方法不受支持并导致未定义的行为.这里:https://developer.apple.com/library/prerelease/ios /documentation/AVFoundation/Reference/AVPlayerViewController_Class/index.html)有没有办法获得通知?
2> Zyphrax..:
Apple没有提供内置方式来处理Done按钮这一事实令人失望.
我不想从AVPlayerViewController继承,因为Apple不支持它,并且可能会在下一个iOS更新中打开一堆蠕虫.
我的解决方法是每200毫秒启动一次计时器并检查以下情况:
if (playerVC.player.rate == 0 &&
(playerVC.isBeingDismissed || playerVC.nextRespOnder== nil)) {
// Handle user Done button click and invalidate timer
}
播放器的rate
属性为0表示视频不再播放.如果视图控制器被解雇或已被解雇,我们可以安全地假设用户单击了完成按钮.
3> Marco Mardeg..:
我通过保留对AVPlayerViewController实例的弱引用并使用计时器将引用更改为nil的计时器来解决。
private weak var _playerViewController : AVPlayerViewController? // global reference
...
...
let playerCOntroller= AVPlayerViewController() // local reference
...
self.present(playerController, animated: true) { [weak self] in
playerController.player?.play()
self?._playerViewCOntroller= playerController
// schedule a timer to intercept player dismissal
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in
if self?.playerViewCOntroller== nil {
// player vc dismissed
timer.invalidate()
}
}