Почему это преобразование с использованием CATransform3D уменьшает ширину представления?
Посмотрите на следующую последовательность изображений:
То, что происходит здесь, сначала я выбрал "Бейсбол", в результате чего 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 ответа
Я решил это. Оказывается, что применение CATransform3D
на самом деле меняет кадр зрения. В коде, который я разместил, когда я устанавливаю новый кадр вида (потому что он поворачивается в другую позицию), я просто использую view.frame.size.width
в CGRectMake()
в попытке сохранить ширину. НО, так как CATransform3D
ранее изменил ширину, я не получаю фактическую ширину, которую я хочу.
Решение состояло в том, чтобы создать подкласс UIViews
и сохраните их оригинальную рамку в иваре. Таким образом, я всегда могу использовать это в качестве контрольной точки при перемещении видов в разные позиции.
Вам не нужно редактировать матрицы 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;
а затем поиграйте с этими углами, пока все не будет выглядеть правильно.