如何在 Objective-C 中收听 Apple TV Remote?
How to listen to Apple TV Remote in Objective-C?
这似乎应该非常简单明了,但我找不到有效的示例、好的文档,甚至是很多有用的 Whosebug 帖子。
我有一个包含 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()
语句,我开始看到这些日志。如果我再次按下暂停按钮,日志就会暂停。我按了第四次,日志又开始了。
为了尝试解决这个问题,我想将一个监听器绑定到遥控器的 play/pause 按钮,并确保如果我正在播放广告,那么 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
而这一次,当我按下 play/pause 按钮时,似乎真的发生了什么。该应用程序崩溃了,Xcode 给了我以下错误:
2019-12-17 12:16:50.937007-0500 Example tvOS App[381:48776] -[_AVPlayerViewControllerContainerView tapped:]: unrecognized selector sent to instance 0x10194e060
所以好像是(如有错误请指正):
- AVPlayerViewController 有焦点,不是我的视图
- 手势识别器在您将其注册到的 class 上调用选择器,而不是进行注册的 class
所以我想我原来的另一个问题是:我如何允许 my class 处理一个其他一些 class(例如 AVPlayerViewController)上的手势?
目标不需要等于手势识别器附加到的视图。您可以将目标设置为 MyView
,但仍将手势识别器附加到 controller.view
要解决 unrecognized selector
崩溃问题,您需要确保提供正确的对象作为手势识别器的 target
。 UIGestureRecognizer
的工作方式是,当手势被识别时,它将在给定的 target
对象上调用给定的 selector
。换句话说,当手势触发时,它将执行相当于:
[target selector:self];
(您似乎将 target
视为手势将附加到的视图,但实际情况并非如此)
因此,如果您在 class MyView
上实现了 tapped:
,那么您传递给手势识别器初始化程序的 target
应该是 [=11= 的一个实例].您可能想提供 self
,而不是 self.view
。
这似乎应该非常简单明了,但我找不到有效的示例、好的文档,甚至是很多有用的 Whosebug 帖子。
我有一个包含 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()
语句,我开始看到这些日志。如果我再次按下暂停按钮,日志就会暂停。我按了第四次,日志又开始了。
为了尝试解决这个问题,我想将一个监听器绑定到遥控器的 play/pause 按钮,并确保如果我正在播放广告,那么 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
而这一次,当我按下 play/pause 按钮时,似乎真的发生了什么。该应用程序崩溃了,Xcode 给了我以下错误:
2019-12-17 12:16:50.937007-0500 Example tvOS App[381:48776] -[_AVPlayerViewControllerContainerView tapped:]: unrecognized selector sent to instance 0x10194e060
所以好像是(如有错误请指正):
- AVPlayerViewController 有焦点,不是我的视图
- 手势识别器在您将其注册到的 class 上调用选择器,而不是进行注册的 class
所以我想我原来的另一个问题是:我如何允许 my class 处理一个其他一些 class(例如 AVPlayerViewController)上的手势?
目标不需要等于手势识别器附加到的视图。您可以将目标设置为 MyView
,但仍将手势识别器附加到 controller.view
要解决 unrecognized selector
崩溃问题,您需要确保提供正确的对象作为手势识别器的 target
。 UIGestureRecognizer
的工作方式是,当手势被识别时,它将在给定的 target
对象上调用给定的 selector
。换句话说,当手势触发时,它将执行相当于:
[target selector:self];
(您似乎将 target
视为手势将附加到的视图,但实际情况并非如此)
因此,如果您在 class MyView
上实现了 tapped:
,那么您传递给手势识别器初始化程序的 target
应该是 [=11= 的一个实例].您可能想提供 self
,而不是 self.view
。