Как отслеживать последовательные преобразования CGAffineTransforms, чтобы достичь определенной точки на экране? - PullRequest
0 голосов
/ 03 декабря 2010

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

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

Например:

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

Как узнать, что нужно перевести, чтобы перейти из Позиции 2 в Позицию 3?

В контексте я пытаюсь достичь iPadсмотрите следующим образом:

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

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

ОБНОВЛЕНИЕ:

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

ОБНОВЛЕНИЕ 2:

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

1 Ответ

0 голосов
/ 10 декабря 2010

Ответ, очевидно, вы не отслеживаете преобразования.

Таким образом, способ вращать панель инструментов вокруг экрана - это , а не , объединяющее вращение и преобразование преобразования. Вместо этого создайте преобразование поворота и установите кадр в блоке анимации. Кроме того, основываясь на новой 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 отображает от вашего имени, не ориентированы правильно. То есть модальные окна и всплывающие окна сохраняют ту же ориентацию, что и базовый UIView. Эта проблема делает все это спорным.

...