2010-12-03 3 views
0

Как выполнить несколько операций CGAffineTransform (в блоках анимации), не отслеживая каждую выполненную операцию?Как отслеживать последовательные CGAffineTransforms, чтобы достичь определенной точки на экране?

Операция перевода не принимает координаты x, y, а вместо этого значения сдвигаются. Поэтому, если вы не знаете, где вы сейчас переведены, скажите в «месте 2», как вы знаете, какие значения нужно сдвинуть, чтобы добраться до «местоположения 3?»?

Например:

кадр

A UIView находится в точке (0, 0) - Позиция 1. Я поставил преобразования, чтобы перевести (768, 0) и поворот -90 градусов - Позиция 2. Через некоторое время проходит и теперь я хочу перейти на (768, 1024) и повернуть еще на -90 градусов - Позиция 3.

Как я могу узнать, что переводить с позиции 2 на позицию 3?

В контексте я пытаюсь достичь зрения IPad вроде следующего:

  • UIView, который занимает весь экран
  • UIToolbar, который занимает верхний край и находится на вершине UIView
  • Когда iPad вращается, UIView остается с устройством, но панель инструментов будет вращаться так, чтобы она всегда находилась на верхнем краю экрана.

Я использую CGAffineTransform для перевода и поворота для перемещения панели инструментов. Отлично работает, за исключением случаев, когда я несколько раз вращаю iPad. Первый перевод/поворот будет работать идеально. Следующие преобразования будут отключены, потому что я не знаю правильных значений для перехода.

UPDATE:

Похоже, если я беру текущий перевод (Тх, Ту) значения в UIView.transform структуры и использовать разницу между ними и на новом месте, она работает. Однако, если представление повернуто, это не сработает. Значения tx и ty могут быть перевернуты из-за предыдущего вращения. Я не уверен, как с этим справиться.

UPDATE 2:

Выполнения некоторых исследований, я обнаружил, что я могу получить оригинальную, неповёрнутую точку из ТХ, ти, получив значение абса точек и, возможно, замены х и у, если UIView перпендикулярен. Теперь я зациклился на том, как правильно применить следующий набор преобразований в правильном порядке. Кажется, что независимо от того, как я их конкатенирую, UIView заканчивается не в том месте. Просто кажется, что это слишком сложно, и должен быть более простой способ.

ответ

0

Ответ, по-видимому, не отслеживает преобразования.

Таким образом, поворот панели инструментов вокруг экрана осуществляется на не конкатенировать поворот и трансформировать преобразование. Вместо этого создайте поворотное преобразование и установите кадр в блоке анимации. Далее, на основе новой UIInterfaceOrientation, установите градусы для вращения на основе значений компаса 0, -90, -180, -270. Кроме того, установите базу размера кадра в тех же местах.

Итак:

CGPoint portrait = CGPointMake(0, 0); 
CGPoint landscapeLeft = CGPointMake(768 - 44, 0); 
CGPoint landscapeRight = CGPointMake(0, 0); 
CGPoint upsideDown = CGPointMake(0, 1024 - 44); 

CGSize portraitSize = CGSizeMake(768, 44); 
CGSize landscapeLeftSize = CGSizeMake(44, 1024); 
CGSize landscapeRightSize = CGSizeMake(44, 1024); 
CGSize upsideDownSize = CGSizeMake(768, 44); 

CGFloat rotation; 
CGRect newLocation; 
switch(orientation) { 
    case UIDeviceOrientationPortrait: 
     NSLog(@"Changing to Portrait"); 
     newLocation.origin = portrait; 
     newLocation.size = portraitSize; 
     rotation = 0.0; 
     break; 

    case UIDeviceOrientationLandscapeRight: 
     NSLog(@"Changing to Landscape Right"); 
     newLocation.origin = landscapeRight; 
     newLocation.size = landscapeRightSize; 
     rotation = -90.0; 
     break; 

    case UIDeviceOrientationLandscapeLeft: 
     NSLog(@"Changing to Landscape Left"); 
     newLocation.origin = landscapeLeft; 
     newLocation.size = landscapeLeftSize; 
     rotation = -270.0; 
     break; 

    case UIDeviceOrientationPortraitUpsideDown: 
     NSLog(@"Changing to Upside Down"); 
     newLocation.origin = upsideDown; 
     newLocation.size = upsideDownSize; 
     rotation = -180.0; 
     break; 

    default: 
     NSLog(@"Unknown orientation: %d", orientation); 
     newLocation.origin = portrait; 
     newLocation.size = portraitSize; 
     rotation = 0.0; 
     break; 
} 

CGRect frame = newLocation; 
CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(rotation)); 

if(lastOrientation) { 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:.3]; 
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 
} 

toolbar.transform = transform; 
toolbar.frame = frame; 

// Commit the changes 
if(lastOrientation) { 
    [UIView commitAnimations]; 
} 

lastOrientation = orientation; 

Это прекрасно работает. Однако неожиданная проблема заключается в том, что элементы пользовательского интерфейса, которые IOS отображает от вашего имени, неправильно ориентированы. I.e., модальные окна и popovers все придерживаются той же ориентации, что и основной UIView. Эта проблема делает все это спорным.

+0

Оказывается, последняя проблема ориентации UIPopover может быть исправлена ​​с помощью 1 лайнера: [[UIApplication sharedApplication] setStatusBarOrientation: ориентация анимированная: NO]; (Тем не менее, модальные окна все еще дурацкие.) – Mike 2010-12-10 19:33:21

Смежные вопросы