MPMoviePlayerController's view does not recognize touch
Solution 1
Actually, answer to this is simple:
- set yourself as UIGestureRecognizer delegate
- return YES for delegate methods:
e.g.
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture)];
tapGestureRecognizer.delegate = self;
and somewhere else in the code:
#pragma mark - gesture delegate
// this allows you to dispatch touches
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return YES;
}
// this enables you to handle multiple recognizers on single view
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Solution 2
MPMoviePlayerController has a subview that takes up its entire bounds, and that subview has 3 gesture recognizers on it (in iOS 4.3).
mp = [[MPMoviePlayerController alloc] initWithURL:movieURL];
mp.frame = aRectangle;
for (UIGestureRecognizer *g in ((UIView *)[mp.view.subviews objectAtIndex:0]).gestureRecognizers) {
NSLog(@"g %@", g);
}
will output:
g <MPTapGestureRecognizer: 0x6224c30; baseClass = UIGestureRecognizer; state = Possible; cancelsTouchesInView = NO; view = <MPSwipableView 0x6416100>; target= <(action=_tapGestureRecognized:, target=<MPSwipableView 0x6416100>)>>
g <UIPinchGestureRecognizer: 0x6224710; state = Possible; cancelsTouchesInView = NO; delaysTouchesEnded = NO; view = <MPSwipableView 0x6416100>; target= <(action=_pinchGestureRecognized:, target=<MPSwipableView 0x6416100>)>>
g <MPActivityGestureRecognizer: 0x6224640; baseClass = UIGestureRecognizer; state = Possible; cancelsTouchesInView = NO; delaysTouchesEnded = NO; view = <MPSwipableView 0x6416100>; target= <(action=_activityGestureRecognized:, target=<MPSwipableView 0x6416100>)>>
So there is already a GestureRecognizer that handles a single tap, but it isn't a UITapGestureRecognizer, but an MPTapGestureRecognizer (a custom recognizer for the movie player).
If you create a generic view and add it to the movie player view hierarchy, you can add touches to it, but it blocks the touches to the movie player (so a single tap won't make the controls disappear).
e.g.
UIView *aView = [[UIView alloc] initWithFrame:mp.view.bounds];
[aView addGestureRecognizer:tapGesture];
[mp.view addSubview:aView];
This will get your tap, but you break the controls. There may still be a way to allow it to interact with the other gestures.
Solution 3
Just to share my different approach for adding a custom UISwipeGestureRecognizer to the player view without adding a custom view:
[[player.view.subviews objectAtIndex:0] addGestureRecognizer:swipeGesture];
This is to replace the conventional method of calling
[player.view addGestureRecognizer:swipeGesture];
as it only works on iPad non-fullscreen mode and on iPhone. When the player goes to fullscreen mode on iPad, the gesture does not work
Solution 4
You can use UIView
UITouch
event for this.
Take a UIView
and put MPMoviePlayerController
inside that:
theMovie = [MPMoviePlayerController new];
theMovie.view.frame = CGRectMake(0, 0, 1024, 768);
[theMovie setContentURL:theURL];
[theMovie setScalingMode:MPMovieScalingModeAspectFit];
[theMovie setCurrentPlaybackTime:0.2];
[theMovie setFullscreen:YES animated:YES];
[self addSubview:theMovie.view];
[viewMovie addSubview:theMovie.view];
Use UIView
touch delegate methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touchesBegan");
UITouch *touch = [touches anyObject];
startPosition = [touch locationInView:self];
[viewMovie touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touchesMoved");
UITouch *touch = [touches anyObject];
CGPoint endPosition = [touch locationInView:self];
if (startPosition.x < endPosition.x)
{
NSLog(@"Left to Right");
}
else
{
NSLog(@"Right to Left");
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}
Where startPosition
is a CGPoint
declared in .h
file.
beryllium
... vom Leben gezeichnet in den buntesten Farben. Я не живу, я слежу за собственной жизни развитием.
Updated on June 03, 2022Comments
-
beryllium about 2 years
This is my code:
_mediaPlayer = [[MPMoviePlayerController alloc] init]; _mediaPlayer.controlStyle = MPMovieControlStyleNone; _mediaPlayer.shouldAutoplay = NO; [_mediaPlayer.view setFrame: CGRectMake(5, 5, 600,400)]; [playerHolder addSubview: _mediaPlayer.view]; // [self prepareScreenContentToPlay]; // UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleRollTap:)]; singleFingerTap.numberOfTapsRequired = 1; [_mediaPlayer.view addGestureRecognizer:singleFingerTap]; [singleFingerTap release];
And action method for gesture recognizer:
-(void)handleRollTap:(UITapGestureRecognizer*)sender{ NSLog(@"%@", @"touch"); }
MPMoviePlayerController works fine. In addition I want to handle touch on MPMoviePlayerController view but
handleRollTap
never called. Why MPMoviePlayerController's view not works with UITapGestureRecognizer?
OK. If
singleFingerTap.numberOfTapsRequired = 2;
then all works fine as well. But nothing for single tap..
-
devdavid almost 13 yearsJust realized you're setting your controlStyle to NONE already, so I guess this should work for you!
-
mdomans over 11 yearsYes. Normaly a gesture recognizer assumes it should do least damage possible. But in rare cases you want to add custom touch recognizers to a view that has his own recognizers, you can set a delegate that can perform resolution when recognizers should work together. Such delegate can decide on every recognizer added to the view. It's a very usefull patern alleviating a lot of pains caused by previous approaches utilising hacking into view internals.
-
Duck over 11 yearssimply B R I L L I A N T !!! I don't understand why your answer is was not accepted as so.
-
Toad about 11 yearsThis didn't seem to work for me. I've added a different solution for people who are still stuck
-
Ege Akpinar about 10 yearsWorks very well. And my belief is, this has to do with the fact that MPMoviePlayerController most probably adds its own tap recogniser (to show/hide player controls for instance) so this delegate pattern allows both to work simultaneously
-
mdomans almost 10 years@EgeAkpinar exactly, MPMoviePlayerController and it views use multiple gesture recognisers
-
mdomans almost 10 years@onmyway133 that's usually the case when your delegate gets deallocated
-
Siten over 8 years[[anyview.subviews objectAtIndex:0] addGestureRecognizer:swipeGesture]; Works like a champ... Bro. well done.
-
Randika Vishman about 8 yearstrick is you giving the hint to add a
swipeGesture
! So it preserves the tap geusture to keep it available the Player controls! Bravo! (Y)