【问题标题】:How to listen to Apple TV Remote in Objective-C?如何在 Objective-C 中收听 Apple TV Remote?
【发布时间】:2020-04-10 05:54:18
【问题描述】:

这看起来应该很简单,但我很难找到一个有效的示例、好的文档,甚至是许多有用的 StackOverflow 帖子。

我有一个包含 AVPlayer 的自定义视图,如下所示:

@implementation
{
    @private
    AVPlayerViewController *controller
}

- (id) init
{
    self = [super init];
    if (self)
    {
        controller = [[AVPlayerViewController alloc] init];
        controller.view.frame = self.view.bounds;
        [self.view addSubview:controller.view];
    }
    return self;
}

@end

(我还有一些其他视图,例如覆盖播放器的消息、我在交换视频时显示的海报等 - 但这是基本设置)

当我集成 IMA SDK 时,我开始遇到问题。如果您在广告期间按下遥控器上的暂停按钮,它会暂停广告就好了。但是,如果您再次按下暂停按钮,它不会取消暂停广告,而是取消暂停广告后面的内容播放器。我没有听到任何音频,但我知道内容播放器没有暂停,因为我的视频中有 ID3 元数据,当我点击它时有一个 NSLog() 声明,我开始看到这些日志。如果我再次按下暂停按钮,日志会暂停。我第四次按下它,日志再次启动。

为了尝试解决这个问题,我想将监听器绑定到遥控器的播放/暂停按钮,并确保如果我正在播放广告,则 ad 已恢复,而不是内容。所以我尝试在我的视图中将以下内容添加到我的init 方法中:

        UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(tapped:)];
        [tapRecognizer setAllowedPressTypes:@[ [NSNumber numberWithInt:UIPressTypePlayPause] ]];
        [self.view addGestureRecognizer:tapRecognizer];

然后我创建了以下方法:

- (void) tapped: (UITapGestureRecognizer *) sender
{
    NSLog(@"Tapped");
}

这没有被调用。我很有信心我犯了一个简单的错误,但文档不是很清楚,所以我不确定我应该做什么。 official documentation on detecting button presses 使用 Swift 并说:

    let tapRecognizer = UITapGestureRecognizer(target: self, action: "tapped:")
    tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)];
    self.view.addGestureRecognizer(tapRecognizer)

相信这三行我翻译得很好。然后,该文档没有显示 tapped 方法应该是什么样子,而是与低级事件处理的工作相切。因此,为了获得适当的方法签名,我查看了the documentation on UITagGestureRecognizer,它具有以下(Swift)示例来编写处理程序:

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .ended {
        // handling code
    }
}

这就是我选择- (void) tapped: (UITapGestureRecognizer *) sender的原因

尽管如此,它仍然无法正常工作。

快速更新

我尝试替换:

initWithTarget:self.view

与:

initWithTarget:controller.view

还有:

self.view addGestureRecognizer

与:

controller.view addGestureRecognizer

这一次,当我按下播放/暂停按钮时,看起来好像真的发生了一些事情。应用程序崩溃了,Xcode 给了我以下错误:

2019-12-17 12:16:50.937007-0500 Example tvOS App[381:48776] -[_AVPlayerViewControllerContainerView tapped:]: unrecognized selector sent to instance 0x10194e060

所以它看起来像(如果我错了,请纠正我):

  • AVPlayerViewController 具有焦点,而不是我的视图
  • 手势识别器在您将其注册到的任何类上调用选择器,而不是在进行注册的类上调用选择器

所以我想我原来的另一个问题是:我如何允许 my 类处理 some other 上的手势em> 类(例如 AVPlayerViewController)?

【问题讨论】:

    标签: objective-c avplayer tvos uitapgesturerecognizer avplayerviewcontroller


    【解决方案1】:

    目标不需要等于手势识别器附加到的视图。您可以将目标设置为MyView,但仍将手势识别器附加到controller.view

    要解决unrecognized selector 崩溃问题,您需要确保为手势识别器提供正确的对象作为targetUIGestureRecognizer 的工作方式是,当手势被识别时,它将在给定的target 对象上调用给定的selector。换句话说,当手势触发时,它将执行相当于:

    [target selector:self];
    

    (您似乎将target 视为手势将附加到的视图,这不是它的工作原理)

    因此,如果您在类MyView 上实现了tapped:,那么您传递给手势识别器初始化程序的target 应该是MyView 的一个实例。您可能想提供self,而不是self.view

    【讨论】:

    • 这是我的问题:我希望 AVPlayerView 接收焦点并处理 99% 的 UI 手势(寻找、更改标题等 - 所有的滑动、按钮按下和点击都应该提供给AVPlayerViewController 用于标准视频播放器行为)。但是我希望 AVPlayerView (我的视图)的 parent 拦截和处理播放/暂停事件。将我的视图作为目标传递给手势识别器不起作用,正如我在原始帖子中所指出的那样,因为我的视图没有焦点。如果我把焦点放在我的视图上,那么我就不能再寻找或更改标题或做任何其他事情了。
    • 手势识别器的“目标”与拥有焦点的人无关。在任何情况下,您都可以创建您想要的任何手势并将其附加到您想要的任何 view,包括 AVPlayerView。您是否尝试过 UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]; [controller.view addGestureRecognizer:tapRecognizer]; 之类的东西? (注意创建手势时self.viewself 之间的区别)
    • 这就是秘诀。我没有意识到我添加UITapGestureRecognizer 的视图不必匹配target。我将UITapGestureRecognizer 添加到的视图与谁拥有焦点有关(当我将它放在不同的视图上时,它从未触发)
    • target 根本不需要是视图(通常不是)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    相关资源
    最近更新 更多