我有一个splashViewController
containerView
,它是在Storyboard中创建的。
在我的故事板中,我会自动将嵌入的segue从containerView
拖到profileViewController
。
在splashViewController
内,我想以编程方式"销毁" containerView
+ profileViewController
(两者都有)。
我试过这个:
self.containerView.hidden = true //obviously doesn't work. it's just visual
self.containerView.removeFromSuperView() //nope. it's just visual.
如何完全删除containerView 和 profileViewController,确保两个deinit
都适当?如果那不可能,我至少可以放弃profileViewController吗? (我只是将containerView设置为隐藏)。
注意:我在profileViewController中自动播放电影视频(循环播放)。它有声音,即使我将containerView设置为nil并从superview中删除它,声音也会继续播放。
答案 0 :(得分:3)
我在这里写了一个快速示例项目来演示解决方案here。
自动播放视频(带有狗吠声)会自动在屏幕底部播放。按“停止播放器”按钮将删除子UIViewController
和容器。
MPMoviePlayerController
也完成了播放音频(如果MPMoviePlayerController
的内部部分保留了我怀疑是问题的强引用,则不一定要解除分配)。
无论如何,在致电contentURL
deinit
上将电影播放器的moviePlayer.stop()
设置为nil,找到了解决方法
//The `ProfileViewController` is created in the storyboard as a child of `ViewController`.
class ViewController: UIViewController {
@IBOutlet weak var container: UIView?
@IBAction func stopPlayer(sender: UIButton) {
//We remove the child view controller (the ProfileViewController) from the parent
for controller in self.childViewControllers {
if let child = controller as? ProfileViewController {
child.removeFromParentViewController() //This causes the deinit call
container?.removeFromSuperview() //Clear up the container (stays as a black box otherwise)
}
}
}
}
在ProfileViewController
中,我们必须更改contentURL并停止我们的电影播放器
class ProfileViewController: UIViewController {
lazy var moviePlayer: MPMoviePlayerController = {
let path = NSBundle.mainBundle().pathForResource("TestMovie", ofType: "mp4")!
let moviePlayer = MPMoviePlayerController(contentURL: NSURL(fileURLWithPath: path)!)
moviePlayer.movieSourceType = .File
moviePlayer.prepareToPlay()
moviePlayer.view.frame = self.view.frame
return moviePlayer
}()
override func viewDidAppear(animated: Bool) {
view.addSubview(moviePlayer.view)
moviePlayer.play()
//Looping
NSNotificationCenter.defaultCenter().addObserver(self, selector: "moviePlayerDidFinish:", name:MPMoviePlayerPlaybackDidFinishNotification, object: moviePlayer)
}
//Change our contentURL then stop
deinit {
moviePlayer.contentURL = nil
moviePlayer.stop()
}
@objc func moviePlayerDidFinish(notification: NSNotification) {
let reasonInt = notification.userInfo![MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] as! Int
let reason = MPMovieFinishReason(rawValue: reasonInt)
if (reason == MPMovieFinishReason.PlaybackEnded) {
moviePlayer.play()
}
}
}
在iPhone 5设备和模拟器上测试
UIView
removeFromSuperview
MPMoviePlayerController
在停止后继续播放音频,这是一个错误。通过设置contentURL然后停止答案 1 :(得分:0)
这里缺少一些细节,所以我会尽力做到最好,但听起来像containerView不是UIViewController的主要视图,因为我不认为你可以说自我。 .removeFromSuperView()
如果您想要一个删除容器视图的模式,我建议您看看Apple如何建议您使用ContainerViewController执行此操作。还有一些步骤涉及但它允许您轻松添加和删除儿童。缺点是您需要将ViewController与每个视图相关联。
这听起来像你正在处理的问题是这个MPMoviePlayerController。 MPMoviePlayerController需要与其关联的视图。来自Apple的文档
在电影播放器拥有的视图中进行播放并进行播放 全屏或内联。您可以合并电影播放器的视图 进入您的应用程序拥有的视图层次结构,或使用 MPMoviePlayerViewController对象为您管理演示文稿。
我的猜测是没有查看任何代码,MPMoviePlayerController挂起对您删除的视图之一的引用及其强引用,因此它不允许您实际删除该视图并使其继续而不在屏幕上。
看起来在ios9中不推荐使用MPMoviePlayerController,因此您应该转移到AVPlayer,这样可以让您更好地控制视图中的电影
答案 2 :(得分:-1)
我认为你应该找到一种方法来停止播放声音。此外,您只需将nil
分配给要解除分配的视图控制器即可。但是,您无法执行self = nil;
。