I want the ability to change how the playback controls are presented while using the new AVPlayerViewController in AVKit. Basically, I want to overide the single finger tap gesture to do something else, and replace that gesture with a double finger tap. I am subclassing AVPlayerViewController to add this functionality.
I can add the double finger tap easily by creating a new UITapGestureRecognizer, but doing so with a single tap does nothing, as the playback controls still appear and my custom gesture method is not called. I assume because the AVPlayerViewController has a gesture with priority that is called instead.
I setup the gestures like normal...
// singleFingerTap: will never fire...
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleFingerTap:)];
singleFingerTap.numberOfTouchesRequired = 1;
singleFingerTap.delegate = self;
[self.view addGestureRecognizer:singleFingerTap];
// doubleFingerTap: will work correctly...
UITapGestureRecognizer *doubleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleFingerTap:)];
doubleFingerTap.numberOfTouchesRequired = 2;
doubleFingerTap.delegate = self;
[self.view addGestureRecognizer:doubleFingerTap];
Any thoughts on how to achieve this without accessing private properties? Is it even permitted? I know I can create my own view controller with an instance of AVPlayer and then create my own playback controls, but I'm hoping I can use the lightweight AVKit player here with a few simple modifications.
I've tried looping through the gestures in AVPlayerViewController's view and removing them, but the gestureRecognizers property was empty. Even if I could do this, I wouldn't know how to add back the gesture to display the playback controls on a double finger tap instead of the single finger tap.
Any suggestions would be much appreciated! Especially whether this is possible/allowed or not. Thanks!
EDIT: I have found a way to explicitly unblock the player's private gesture that was blocking my own gesture.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
id firstGesture = gestureRecognizer;
id secondGesture = otherGestureRecognizer;
if ([firstGesture isKindOfClass:[UITapGestureRecognizer class]] && [secondGesture isKindOfClass:[UITapGestureRecognizer class]]) {
UITapGestureRecognizer *tapGesture = firstGesture;
UITapGestureRecognizer *otherTapGesture = secondGesture;
if (tapGesture.numberOfTapsRequired == otherTapGesture.numberOfTapsRequired && tapGesture.numberOfTouches == otherTapGesture.numberOfTouches) {
// Disable the single tap that shows the playback controls...
return YES;
}
}
return NO;
}
This effectively prevents the playback controls from appearing on a tap, and my singleTapGesture: fires as expected. However, I now have the issue of getting the playback controls to appear on a different gesture. Is it possible to reroute the private gesture, or simulate the private gesture programmatically?
Why not just check/modify the target/remove the default gesture recognizers first?
You can access them with the standard UIView
's gestureRecognizers
.
The gestures recognizers may be buried inside a private subview.
Another solution would be to set userInteractionEnabled
to NO
and add your gesture recognizers to the superview or to a "overlay" transparent view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With