AVPlayer UITapGestureRecognizer не работает

У меня есть этот код для моего AVPlayerViewController.

UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAvPlayer)];
[self.avPlayerViewController.view addGestureRecognizer:tap];

но это не работает .. :S, я попытался установить

[self.avPlayerViewController.view setUserInteractionEnabled:YES];

все равно не годится..

Единственное рабочее решение - использовать UIGestureRecognizer и реализовать его делегат shouldReceiveTouch и проверить, коснулся ли AV-плеер.. но проблема в том, что мы не хотим захватывать событие «выпуск касания»... потому что, если представление av player просто коснулось , он немедленно выполняет код, а это не то, что мы хотели...

Помогите пожалуйста с этим вопросом..

Спасибо!


person GinealSoftwareDev    schedule 27.04.2016    source источник


Ответы (8)


Или вы можете создать подкласс AVPlayerViewController и использовать следующий метод для

получить контроль: -

1.touchBegan 2.touchEnd

Убедитесь, что вы установили этот флаг self.avPlayerContr.showsPlaybackControls = false

Надеюсь, что это работает для вас.

person Nitesh    schedule 27.04.2016
comment
Переопределение методов UIControl — это хак. Предпочтительный подход — с contentOverlayView (см. мой ответ). - person TyR; 15.02.2018

Правильным местом для обработки жестов в AVPlayerViewController является contentOverlayView контроллера.

contentOverlayView — это свойство AVPlayerViewController, доступное только для чтения. Это вид, который отображается поверх видео, но под контроллером. Просто идеальное место для сенсорного управления. Вы можете добавить к нему подпредставления или обработчики жестов во время загрузки.

Следующий код обеспечивает сенсорную поддержку вашего видеоконтроллера двумя способами, чтобы продемонстрировать подходы как к распознаванию жестов, так и к UIButton.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"mySegue"])
    {
        // Set things up when we're about to go the the video
        AVPlayerViewController *avpvc = segue.destinationViewController;
        AVPlayer *p = nil;
        p = [AVPlayer playerWithURL:[NSURL URLWithString:@"https://my-video"]];
        avpvc.player = p;

        // Method 1: Add a gesture recognizer to the view
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myAction:)];
        avpvc.contentOverlayView.gestureRecognizers = @[tap];

        // Method 2: Add a button to the view
        UIButton *cov = [UIButton buttonWithType:UIButtonTypeCustom];
        [cov addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
        cov.frame = self.view.bounds;
    }
}

(на самом деле не для написания версии Swift на данный момент, извините. :)

person TyR    schedule 14.02.2018
comment
У меня есть AVPlayerViewController, который отвечает за воспроизведение видео внутри пользовательского UITableViewCell. Метод добавления распознавателя жестов в contentOverlayView не работает. Каким-то образом касания перехватываются, как только представление игрока добавляется в ячейку. Любые мысли о том, что я мог бы сделать, чтобы обойти эту проблему? Спасибо! - person Stoph; 11.07.2019
comment
@Stoph Вы наконец нашли решение? - person Zigii Wong; 29.06.2021
comment
@ZigiiWong, мне пришлось вернуться и покопаться в своем коде, но я нашел свое решение. В итоге я создал собственный подкласс AVPlayerViewController и переопределил метод - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event. Переопределенный метод вызывает настраиваемый интерфейс делегата, который принимает событие касания для выполнения любого необходимого мне действия. - person Stoph; 29.06.2021

Это должно сделать это. Вместо этого добавьте распознаватель в подпредставление проигрывателя:

[videoPlayerViewController.view.subviews[0] addGestureRecognizer:tap]

Это было быстрое решение для сложного пользовательского интерфейса, а жесты заглядывают в contentOverlayView, см. ответ TyR.

person Radu    schedule 15.02.2017
comment
Я пытался заставить это работать в течение недели, и это все, что мне потребовалось. Красивый. Спасибо, чувак, ты действительно спас меня. - person user3286381; 24.07.2017
comment
В iOS 11 это приводит к сбою приложения. - person Andrea Mario Lufino; 17.09.2017
comment
iOS 11 все еще находится в бета-версии, посмотрю позже. - person Radu; 19.09.2017
comment
кто-нибудь может подтвердить, что он все еще падает на финальной версии v11? - person sigi; 13.10.2017
comment
Использует недокументированный SPI. Предпочтительный подход — с contentOverlayView (см. мой ответ). - person TyR; 15.02.2018
comment
В iOS 12 это приводит к сбою приложения. - person Will; 25.02.2019

Насколько мне известно, вы действительно хотите

UILongPressGestureRecognizer

Потому что,

UITapGestureRecognizer

Не имеет события типа выпуска, если вы добавите

UILongPressGestureRecognizer

на ваш

avPlayerViewController

Затем в

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
  if ( [gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] ) {

  }
  return YES;
}

Затем вы можете установить минимальную продолжительность жеста, чтобы лучше чувствовать,

[holdGesture setMinimumPressDuration:0.01]

Затем вы можете реализовать метод,

- (void)holdAction:(UILongPressGestureRecognizer *)holdRecognizer

Затем проверьте состояние распознавателя и выполните желаемую функциональность.

person Avinash Sharma    schedule 27.04.2016

Вы можете добавить transparent представление к avplayerViewController и можете добавить tapgesturerecognizer к этому представлению. надеюсь, это поможет :)

person Ketan Parmar    schedule 27.04.2016

Простое решение — добавить режим просмотра жестов в том же представлении держателя фильма после добавления проигрывателя фильмов. Нет необходимости добавлять распознаватель жестов непосредственно в проигрыватель фильмов.

  [self.movieHolderView addSubview:self.moviePlayer.view];


  [self.movieHolderView addSubview:self.gestureView];
  [self.movieHolderView bringSubviewToFront:self.gestureView];

Теперь мы можем добавить наш распознаватель жестов в представление жестов следующим образом.

self.fullScreenTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapHandler:)];
self.fullScreenTapGesture.numberOfTapsRequired = 1;
[self.gestureView addGestureRecognizer:self.fullScreenTapGesture];
person Vinu David Jose    schedule 16.11.2017

Свифт 4

Добавьте распознаватель жестов в представление AVPlayerViewController:

func playVideo() {
    let playerController = AVPlayerViewController()
    playerController.player = AVPlayer(url: URL(fileURLWithPath: videoPath))
    playerController.showsPlaybackControls = false
    playerController.view.isUserInteractionEnabled = true

    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeUp.direction = UISwipeGestureRecognizerDirection.up
    playerController.view.addGestureRecognizer(swipeUp)

    present(playerController, animated: false) {
        playerController.player?.play()
    }
}

@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    print("swipe up")
}
person Zoltan Vinkler    schedule 01.03.2019

Распознаватель жестов должен быть добавлен по-разному для ОС 11 и более ранних версий:

Универсальное решение (Swift 4):

let tap = UITapGestureRecognizer(target: self, action: #selector(videoTap))

if #available(iOS 11.0, *) {
    playerVC?.contentOverlayView?.gestureRecognizers = [tap]
} else {
    playerVC?.view.subviews.first?.addGestureRecognizer(tap)
}

@objc func videoTap(_ button: UIButton) {
    print("Tapped on video")
}
person Александр Бабич    schedule 10.01.2019