2014-09-05 6 views
1

Мое приложение использует CMMotionManager для отслеживания движения устройства, но iOS всегда возвращает данные о движении устройства в стандартной ориентации устройства (кнопка дома внизу).Как настроить данные CMMotionManager для ориентации в iOS 8?

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

CGAffineTransform transform = self.view.transform; 
for (UIView *superview = self.view.superview; superview; superview = superview.superview) { 
    CGAffineTransform superviewTransform = superview.transform; 
    transform = CGAffineTransformConcat(transform, superviewTransform); 
} 

Это преобразование получает рассчитывается корректно под IOS 6 & 7, но iOS 8 изменяет модель вращения, и теперь представления всегда возвращают преобразование идентичности (без вращения) независимо от того, как устройство ориентировано. Однако данные от менеджера движения все еще фиксированы в стандартной ориентации.

Мониторинг уведомлений о вращении UIDevice и ручной расчет четырех преобразований походит на один подход к получению этого преобразования под iOS 8, но это также кажется плохим, поскольку ориентация устройства не обязательно соответствует ориентации моего представления (то есть, вверх на iPhone является ориентация устройства не поддерживается нормально).

Каков наилучший способ получить результат от CMMotionManager в ориентации конкретного UIView под iOS 8?

ответ

0

Я не мог найти способ непосредственно вычислить преобразование, так что вместо этого я изменил мой код, чтобы вычислить набор преобразования вручную при willRotateToInterfaceOrientation: сообщение получено на мой взгляд контроллера, например:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    CGAffineTransform transform; 
    switch (toInterfaceOrientation) { 
     case UIInterfaceOrientationLandscapeLeft: 
      transform = CGAffineTransformMake(
       0, -1, 
       1, 0, 
       0, 0); 
      break; 

     case UIInterfaceOrientationLandscapeRight: 
      transform = CGAffineTransformMake(
       0, 1, 
       -1, 0, 
       0, 0); 
      break; 

     case UIInterfaceOrientationPortraitUpsideDown: 
      transform = CGAffineTransformMake(
       -1, 0, 
       0, -1, 
       0, 0); 
      break; 

     case UIInterfaceOrientationPortrait: 
      transform = CGAffineTransformIdentity; 
      break; 
    } 
    self.motionTransform = transform; 
} 
1

Хотя это не очень очевидно, рекомендуемый способ сделать это в iOS 8 и более поздних версиях - с координаторами перехода.

В viewWillTransition(to:with:), координатор может передать вам экземпляр принимающий UIViewControllerTransitionCoordinatorContext в достройке блоках того из его методов вы называете (координатор по умолчанию используется UIKit на самом деле его собственный контекст, но это не обязательно так).

Свойство контекста targetTransform - это поворот, применяемый к интерфейсу к концу анимации. Обратите внимание, что это родственник преобразование, а не итоговое абсолютное преобразование интерфейса.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    super.viewWillTransition(to: size, with: coordinator) 

    let animation: (UIViewControllerTransitionCoordinatorContext) -> Void = { context in 
     // your animation 
    } 

    coordinator.animate(alongsideTransition: animation) { context in 
     // store the relative rotation (or whatever you need to do with it) 
     self.transform = context.targetTransform 
    } 
} 

Хотя старый подход все еще работает, этот API, по-видимому больше в соответствии с будущим направлением рамок пользовательского интерфейса от Apple, и это позволит более гибко, когда вам нужно контролировать анимированные переходы.

+0

Спасибо за понимание –

+0

Нет проблем! Надеемся, что это поможет другим людям найти то же самое. –