Как получить события движения с помощью пульта Apple TV

Кто-нибудь понял, как заставить события движения работать с новым пультом Apple TV? Спасибо.

я пытался позвонить

override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?) {
    super.motionBegan(motion, withEvent: event)
    print("motion!")
}
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?) {
    super.motionEnded(motion, withEvent: event)
    print("motion ended!")
}

Со звонком super и без него ничего мне не дает.


person CodyMace    schedule 28.09.2015    source источник
comment
Вы получили физический комплект разработчика или используете симулятор?   -  person Tom Elliott    schedule 29.09.2015
comment
Вот статья об этом на форуме разработчиков приложений: forums.developer.apple.com/thread/18861   -  person Stefan    schedule 29.09.2015


Ответы (3)


Отличный быстрый пример можно найти здесь: https://forums.developer.apple.com/message/65560#65560 Это в основном то, что сказал Дэниел Сторм выше, но после этого у меня это сработало. Вот что я сделал.

В делегате приложения:

 var motionDelegate: ReactToMotionEvents? = nil   

     func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {  
        let center = NSNotificationCenter.defaultCenter()  
        center.addObserver(self, selector: "setupControllers:", name: GCControllerDidConnectNotification, object: nil)  
        center.addObserver(self, selector: "setupControllers:", name: GCControllerDidDisconnectNotification, object: nil)  
        GCController.startWirelessControllerDiscoveryWithCompletionHandler { () -> Void in  

        }  
        return true  
    }  

    func setupControllers(notif: NSNotification) {  
        print("controller connection")  
        let controllers = GCController.controllers()  
        for controller in controllers {  
            controller.motion?.valueChangedHandler = { (motion: GCMotion)->() in  
                if let delegate = self.motionDelegate {  
                    delegate.motionUpdate(motion)  
                }  
            }  
        }  
    }  

protocol ReactToMotionEvents {  
    func motionUpdate(motion: GCMotion) -> Void  
}  

Где я хочу, чтобы это было реализовано, в моем случае SKScene:

import SpriteKit  
import GameController  
class GameScene: SKScene, ReactToMotionEvents {  

    override func didMoveToView(view: SKView) {   
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate  
        appDelegate.motionDelegate = self  

    }  

    func motionUpdate(motion: GCMotion) {  
        print("x: \(motion.userAcceleration.x)   y: \(motion.userAcceleration.y)")  
    }  
}  
person CodyMace    schedule 01.10.2015

Через Как получить доступ к информации о движении и ориентации удаленного устройства:


Прежде всего, нужно использовать NSNotificationCenter для поиска контроллеров. Вероятно, лучше всего сделать это при запуске приложения. Что-то вроде этого:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidConnect:) name:GCControllerDidConnectNotification object:nil];  

Затем мы можем использовать следующий код после подключения, чтобы сохранить информацию об устройстве в свойстве:

- (void)controllerDidConnect:(NSNotification *)notification {  
    self.myController = notification.object;  
}  

Удаленный профиль является подклассом профиля микрогеймпада. Движение и другие данные можно отслеживать, добавив обработчик события изменения значения:

  GCMicroGamepad *profile =  self.myController.microGamepad  
  profile.valueChangedHandler= ^ (GCMicroGamepad *gamepad, GCControllerElement *element) {  
        if (self.myController.motion) {  
            NSLog(@"motion supported");  
            NSLog(@"gravity: %f %f %f", self.myController.motion.gravity.x, self.myController.motion.gravity.y, self.myController.motion.gravity.z);  
            NSLog(@"userAcc: %f %f %f", self.myController.motion.userAcceleration.x, self.myController.motion.userAcceleration.y, self.myController.motion.userAcceleration.z);  
            NSLog(@"rotationRate: %f %f %f", self.myController.motion.rotationRate.x, self.myController.motion.rotationRate.y, self.myController.motion.rotationRate.z);  
            NSLog(@"attitude: %f %f %f %f", self.myController.motion.attitude.x, self.myController.motion.attitude.y, self.myController.motion.attitude.z, self.myController.motion.attitude.w);  
        }  
    };  

person Daniel Storm    schedule 29.09.2015
comment
Спасибо, есть идеи, как написать этот последний шаг в Swift? Кроме того, не могли бы вы предложить настроить его в appDelegate, а затем в моем приложении просто получать данные оттуда? - person CodyMace; 29.09.2015
comment
Я пробую это на tvos 9.1 и получаю обновления движения только для self.myController.motion.valueChangedHandler - person JakubKnejzlik; 16.12.2015

Думал, что обновлю отличный ответ CodyMace с помощью синтаксиса Swift 4.0.

В appDelegate (здесь вам также нужно будет импортировать GameController):

var motionDelegate: ReactToMotionEvents? = nil


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    let center = NotificationCenter.default
    center.addObserver(self, selector: #selector(setupControllers), name: NSNotification.Name.GCControllerDidConnect, object: nil)
    center.addObserver(self, selector: #selector(setupControllers), name: NSNotification.Name.GCControllerDidDisconnect, object: nil)
    GCController.startWirelessControllerDiscovery { () -> Void in

    }
    return true
}

@objc func setupControllers(notif: NSNotification) {
    print("controller connection")
    let controllers = GCController.controllers()
    for controller in controllers {
        controller.motion?.valueChangedHandler = { (motion: GCMotion)->() in
            if let delegate = self.motionDelegate {
                delegate.motionUpdate(motion: motion)
            }
        }
    }
}

Протокол остается прежним

protocol ReactToMotionEvents {
func motionUpdate(motion: GCMotion) -> Void

}

И где вы хотите реализовать

import SpriteKit  
import GameController  
class GameScene: SKScene, ReactToMotionEvents {  

    override func didMoveToView(view: SKView) {   
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.motionDelegate = self

    }  

    func motionUpdate(motion: GCMotion) {  
        print("x: \(motion.userAcceleration.x)   y: \(motion.userAcceleration.y)")  
    }  
}  
person D. Pratt    schedule 21.10.2017