Allow Siri Remote Menu button when Play/Pause button is overridden
To return to the Apple TV home screen you can setup a UITapGestureRecognizer
in your viewDidLoad
like so:
// Setup Menu Button recognizer
let menuGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleMenuGesture(_:)))
menuGesture.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)]
self.view.addGestureRecognizer(menuGesture)
and then in handleMenuGesture
you suspend
your application:
// MARK: - Handle Siri Remote Menu Button
func handleMenuGesture(tap: UITapGestureRecognizer) {
print("Menu Gesture")
UIControl().sendAction(#selector(NSURLSessionTask.suspend), to: UIApplication.sharedApplication(), forEvent: nil)
}
Related: Siri Remote's Menu Button not exiting application when UIButton is focused
How to access Siri Remote play/pause button and override menu button
I solved my problem by moving the tapRecognizer
selector into my previously set up touch handler function so the code looks like this now:
private func handleTouches(touches: Set<UITouch>) {
for touch in touches {
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)];
self.view!.addGestureRecognizer(tapRecognizer)
}
}
func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}
Siri Remote's Menu Button not exiting application when UIButton is focused
UIButton
only responds to the .Select
button on the remote. You can catch the menu button using a tap gesture recognizer. For example:
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(ClassName.menuPressed()))
tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)];
view.addGestureRecognizer(tapRecognizer)
Then implement:
func menuPressed() {
// do something
}
Override Apple Siri remote Menu Button Default behavior
You can register a tapGestureRecognizer
and set allowedPressTypes = UIPressTypeMenu
code like so:
UITapGestureRecognizer *tapGestureRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
tapGestureRec.allowedPressTypes = @[@(UIPressTypeMenu)];
[self.view addGestureRecognizer:tapGestureRec];
Then whenever the Siri remotes menu button is pressed your handleTap
method will be called, allowing you to add any custom logic you need. Just be aware that blocking the menu button from suspending your application on the root view controller can be a cause for App Store rejection.
You can get more information about detecting gestures here and about pressTypes here.
How to detect Apple TV Siri Remote button presses?
Apple suggests using a UITapGestureRecognizer
to detect when a button is released.
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController {
UITapGestureRecognizer *tapRecognizer;
}
-(void)viewDidLoad {
[super viewDidLoad];
tapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
tapRecognizer.allowedPressTypes = @[[NSNumber numberWithInteger:UIPressTypeMenu]];
[self.view addGestureRecognizer:tapRecognizer];
}
-(void)handleTap:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(@"Menu button released");
}
}
For a complete list of UIPressType
's refer to UIPress Class Reference.
unable to intercep Pause button on SiriRemote - always stops the background music and never resumes it
to elaborate on my comment above, this is how it could look depending on what kind of gestures you want/need.
Advantage with recognizers is that you can add them to any SKScene instead of managing button presses through the gameViewController and delegates/protocols. Its much easier and works great.
func loadTVGameControls() {
// main (select) button
let tapMain = UITapGestureRecognizer()
tapMain.addTarget(self, action: "pressedTVRemoteSelectButton")
tapMain.allowedPressTypes = [NSNumber (integer: UIPressType.Select.rawValue)]
self.view!.addGestureRecognizer(tapMain)
// play pause
let tapPlayPause = UITapGestureRecognizer()
tapPlayPause.addTarget(self, action: "pressedTVRemotePlayPauseButton")
tapPlayPause.allowedPressTypes = [NSNumber (integer: UIPressType.PlayPause.rawValue)]
self.view!.addGestureRecognizer(tapPlayPause)
// menu
let tapMenu = UITapGestureRecognizer()
tapMenu.addTarget(self, action: "pressedTVRemoteMenuButton")
tapMenu.allowedPressTypes = [NSNumber (integer: UIPressType.Menu.rawValue)]
self.view!.addGestureRecognizer(tapMenu)
// swipe right
let rightSwipe = UISwipeGestureRecognizer(target: self, action: "swipedRightTVRemote")
rightSwipe.direction = UISwipeGestureRecognizerDirection.Right
self.view!.addGestureRecognizer(rightSwipe)
// swipe left ...
// swipe up ...
// swipe down ...
}
func pressedTVRemoteSelectButton() {
// do something
}
func pressedTVRemotePlayPauseButton() {
// do something
}
func pressedTVRemoteMenuButton() {
// do something
}
func swipedRightTVRemote() {
// do something
}
You can do different methods for different scenarios.
In my game I just converted to tvOS I have 1 like the example above and than 2 more like this in my GameScene.swift
1) loadTVPauseControls() // new gestures for when game is paused
2) loadTVGameOverControls() // new gestures for when game is game over
Simply use the below method to disable the gestures before you change them or when you transition to a new scene.
// MARK: - Disable All Gestures
func disableAllGestures() {
guard let view = view else { return }
guard view.gestureRecognizers != nil else { return }
for gesture in view.gestureRecognizers! {
if let tapRecognizer = gesture as? UITapGestureRecognizer {
view.removeGestureRecognizer(tapRecognizer)
}
if let swipeRecognizer = gesture as? UISwipeGestureRecognizer {
view.removeGestureRecognizer(swipeRecognizer)
}
}
}
Related Topics
Realm + Nstableview + Nsarraycontroller
How to Stop Playback of Avplayerviewcontroller as UIviewrepresentable After Dismissal
Swift-Animate Cashapelayer Stroke Color
Swiftui Conditional View Transitions Are Not Working
How to Put a View with Loadmore Button in UItableview After The Cell
Social Framework Is Deprecated in iOS11
Cocos2D Fcm Push Notification Not Working
Prefix(_ Maxlength:) Is Type-Erased When Used with a Struct That Conforms to Lazysequenceprotocol
Swift Ensembles Set Up & Ubiquitycontaineridentifier
How to Center Nspopover When Using Swiftui
Nsdocumentcontroller.Opendocument Not Allowing Selection of Custom File Type
Nssavepannel - How to Restrict User to Only Save One One Set Directory
Convert Gregorian Date to Hijri Date
Cannot Use Mutating Member on Immutable Value of Type 'string'