4

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!

mikejd
  • 1,540
  • 13
  • 18

2 Answers2

6

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.

Community
  • 1
  • 1
mikejd
  • 1,540
  • 13
  • 18
  • 2
    Keep it. I went through the same debugging process you did, so "AVTouchIgnoringView" was what led me here and short-pathed me to a fix. Thanks! :-) – Jolly Roger Apr 12 '16 at 17:32
  • I knew it was a bad idea adding my player viewcontroller to my imageview lol, I deserve this. Great question! – Allison Jun 26 '17 at 23:19
1

Another possible answer is that the player is inside a scrollview with ambiguous height. I ran into this and tried setting user interaction and the frame but no change. Once I set a static height on the content it worked fine.

Ryan Stone
  • 27
  • 1
  • 9