Почему это преобразование с использованием CATransform3D уменьшает ширину вида? - PullRequest
5 голосов
/ 17 января 2012

Посмотрите на следующую последовательность изображений:

enter image description here enter image description here enter image description here

То, что происходит здесь, - сначала я выбрал «Бейсбол», в результате чего 3 серых видаВы видите, что поворачиваете влево, чтобы один с различными уровнями находился посередине (второе изображение).Вы можете видеть, что уже в этот момент ширина представления была существенно уменьшена.Третье изображение появляется после щелчка по представлению, содержащему спортивные имена, в результате чего оно поворачивается обратно к середине.

Из того, что я могу сказать, ширина представления уменьшается, когда он поворачивается в середину.Но я понятия не имею, почему.

Вот соответствующий код.pos относится к месту, где будет находиться рассматриваемый view.0 означает, что он посередине, 1 означает, что он справа от середины, -1 - слева от середины и т. Д.

- (void)perspectiveView:(MenuSection *)view forPosition:(NSInteger)pos
{

    CALayer *layer = view.layer;
    CATransform3D transform = CATransform3DIdentity;

    MenuSection *prevView = (pos >= 0) ? (MenuSection *)[self viewWithTag:view.tag - 1] : (MenuSection *)[self viewWithTag:view.tag + 1];

    if (pos == 0) {
        view.changingToFrame = CGRectMake(round((480 - view.frame.size.width)/2), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
        view.frame = view.changingToFrame;

    } else {

        if (pos == 1) {
            NSLog(@"%@",NSStringFromCGRect(prevView.changingToFrame));
            view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
            transform.m34 = 1.0 / 1000;
        } else if (pos == -1){
            view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
            transform.m34 = 1.0 / -1000;
        } else if (pos == 2){
            view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
            transform.m34 = 1.0 / 500;
        } else if (pos == -2){
            view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
            transform.m34 = 1.0 / -500;
        }

        view.frame = view.changingToFrame;

        transform = CATransform3DRotate(transform, 45.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
    }

    layer.transform = transform;
}

Ответы [ 2 ]

7 голосов
/ 25 января 2012

Я решил это. Оказывается, что применение CATransform3D фактически меняет рамку вида. В коде, который я разместил, когда я устанавливаю новый кадр вида (потому что он поворачивается в другую позицию), я просто использую view.frame.size.width в CGRectMake() в попытке сохранить ширину. НО, поскольку CATransform3D ранее изменил ширину, я не получаю фактическую ширину, которую хочу.

Решение состояло в том, чтобы создать подкласс необходимых UIViews и сохранить их исходный кадр в иваре. Таким образом, я всегда могу использовать это в качестве контрольной точки при перемещении видов в разные позиции.

0 голосов
/ 24 января 2012

Вам не нужно редактировать матрицы CATransform3D напрямую (m34 и т. Д.), Чтобы этот эффект работал.Попробуйте это:

if (pos == 0) {
     view.changingToFrame = CGRectMake(round((480 - view.frame.size.width)/2), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
    view.frame = view.changingToFrame;
} else {
    if (pos == 1) {
         view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
        transform = CATransform3DRotate(transform, M_PI/4.0f, 0.0f, 1.0f, 0.0f);
    } else if (pos == -1){
        view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
        transform = CATransform3DRotate(transform, -M_PI/4.0f, 0.0f, 1.0f, 0.0f);
    } else if (pos == 2){
        view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x + prevView.frame.size.width + 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
        transform = CATransform3DRotate(transform, M_PI/3.0f, 0.0f, 1.0f, 0.0f);
    } else if (pos == -2){
        view.changingToFrame = CGRectMake(round(prevView.changingToFrame.origin.x - view.frame.size.width - 20), view.frame.origin.y, view.frame.size.width, view.frame.size.height);
        transform = CATransform3DRotate(transform, -M_PI/3.0f, 0.0f, 1.0f, 0.0f);
    }
    view.frame = view.changingToFrame;
}
layer.transform = transform;

, а затем поиграйте с этими углами, пока он не будет выглядеть правильно.

...