How do I intercept tapping of the done button in AVPlayerViewController?

前端 未结 10 683
渐次进展
渐次进展 2021-01-03 22:45

I created an AVPlayerViewController and an attached AVPlayer in the viewDidAppear method of a custom UIViewController. Ho

10条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-03 23:06

    Can't believe nobody introduced the most obvious solution: just fire a notification or do whatever you need in AVPlayerViewController's -dealloc method. Just don't hold a strong reference to it, otherwise -dealloc won't be called.

    There's nothing wrong with subclassing AVPlayerViewController (even if docs say otherwise), if you don't break internal logic (e.g. not calling super from overridden methods). I've been using the following code for years (since iOS 8 came out) without any runtime or AppStore submission issues:

    @interface VideoPlayerViewController : AVPlayerViewController
    @end
    
    @implementation VideoPlayerViewController
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }
    @end
    
    // now use VideoPlayerViewController instead of AVPlayerViewController
    

    So, to answer the question, just add this to AVPlayerViewController subclass:

    - (void)dealloc {
      // player was dismissed and is going to die, do any cleanup now
    }
    

    If you are really afraid to subclass, then use smart technique by attaching an associated object to AVPlayerViewController, whose -dealloc you can control, see here: https://stackoverflow.com/a/19344475


    To comment on other solutions:

    • timers: use as last resort only, don't clutter your code with timers
    • use property observation to know when AVPlayer's rate becomes 0.0f and check AVPlayerViewController's isBeingDismissed: clever, but fails when player is paused beforehand (doing it with timer instead works, of course)
    • use AVPlayerViewController's -viewWillDisappear:: might fail when something is presented on top of the player, e.g. built-in subtitle selector. A similar solution would be checking in -viewWillAppear: of the presenting view controller if a player was presented before and should work 100% of the time.
    • adding another action to the Close button: I used this solution for a long time successfully on iOS 8-13, but it suddenly stopped working after I switched from Xcode 9 to 10 (i.e. raised iOS SDK used for building from 11 to 12)

提交回复
热议问题