Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded AVPlayerControllerView adds AVTouchIgnoringView blocking default player's interface

UPDATE: The issue has nothing to do with AVPlayerControllerView, please see my answer below. Name of the class AVTouchIgnoringView confused me in the beginning, but that was also a wrong path of thinking about the problem.

===

As we all know, Media Player framework is deprecated in iOS 9, so I decided to try AVKit instead in my new project. My task is to show a video player embedded inside collection view' header (UICollectionReusableView) with some arbitrary cells below.

This is how I did this in code:

override func viewDidLoad() {
  super.viewDidLoad()

  apiManager.loadVideo() { video in
    let player = AVPlayer(URL: video.url)
    self.playerViewController.view.hidden = true
    self.playerViewController.player = player
    self.addChildViewController(self.playerViewController)

    headerView.videoContainerView.addSubview(self.playerViewController.view)
    Cartography.layout(self.playerViewController.view,
      headerView.videoContainerView) { (v1, v2) in
        v1.leading == v2.leading
        v1.bottom == v2.bottom
        v1.trailing == v2.trailing
        v1.top == v2.top
    }

    self.playerViewController.didMoveToParentViewController(self)
    self.playerViewController.addObserver(self,
      forKeyPath: KeyPath.ReadyForDisplay, options: nil, context: nil)
  }
}

override func observeValueForKeyPath(keyPath: String,
  ofObject object: AnyObject, change: [NSObject : AnyObject],
  context: UnsafeMutablePointer<Void>) {
    if keyPath == KeyPath.ReadyForDisplay {
      dispatch_async(dispatch_get_main_queue()) {
      self.finishConstructingInterface()
    }
  }
}

func finishConstructingInterface() {
  if playerViewController.readyForDisplay == false {
    return
  }
  playerViewController.removeObserver(self, forKeyPath: KeyPath.ReadyForDisplay)
  playerViewController.view.hidden = false
  playerViewController.view.userInteractionEnabled = true
}

This kind of works, the player works as expected, but I'm getting one strange problem: its default interface doesn't respond to touches. To understand the issue, I took a look at view debugger, and what I found there was AVTouchIgnoringView on the top blocking the interface:

AVTouchIgnoringView on the top

So my question is following: what is that AVTouchIgnoringView and why does it interfere with video player interface? And how to get rid of it? Maybe there's some very obvious reason which I just doesn't see?

Thank you for any help!

like image 561
mikejd Avatar asked Mar 14 '23 23:03

mikejd


1 Answers

Ok, solved the problem, and it's completely unrelated to AVPlayerViewController. The reason was that player view container in my case is a subclass of UIImageView, which overrides userInteractionEnabled to NO:

This property is inherited from the UIView parent class. This class changes the default value of this property to NO.

So setting this attribute to YES fixed this issue. Not sure whether I should keep this question or delete it as somewhat confusing the reader.

like image 161
mikejd Avatar answered May 13 '23 16:05

mikejd