Поверните UIView, чтобы дать перспективу

Я хочу изменить перспективу UIView, которая находится в моем Viewcontroller. Я думаю, что мне нужно преобразовать этот слой UIView, но я не знаю, как это сделать.

Я пробовал следующий код, но он не работает

UIView *myView = [[self subviews] objectAtIndex:0];
CALayer *layer = myView.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 45.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;

Я также пробовал со следующим кодом:

-(void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform.b = -0.1;
    transform.a = 0.9;
    CGContextConcatCTM(ctx,transform);
    // do drawing on the context
}

и это тоже:

CALayer *layerA = [[self.view.layer sublayers] objectAtIndex:0];


    layerA.transform = CATransform3DConcat(layerA.transform, CATransform3DMakeRotation(DEGREES_TO_RADIANS(45),1.0,0.0,0.0)

Ни один из них не работал. Как я могу изменить перспективу UIView?

Другими словами, я приведу пример. Представьте этот пример кода, круговая диаграмма вращения образец круговой диаграммы вращения. Я хотел бы изменить перспективу, по осям x или z.


person Aitul    schedule 16.10.2012    source источник


Ответы (1)


Ваше первое решение работает с моей стороны. Это выглядит так:

введите здесь описание изображения

Можете ли вы показать весь код вашего класса, если он не работает с вашей стороны?

ИЗМЕНИТЬ

Хорошо, я перенастроил предоставленный пример кода, чтобы показать, как это возможно:

(скачайте здесь обновленный пример кода: http://www.speedyshare.com/dz469/download/Wheel-demo.zip)

И это выглядит так:

введите здесь описание изображения

Я применяю преобразование только к базовому подразделу. Все представления, являющиеся подвидами этого представления, также будут преобразованы. Если вы хотите, чтобы соответствующее подпредставление имело другое преобразование - это будет сложнее, потому что тогда вы должны принять во внимание преобразование родительского представления, чтобы вычислить новое - это может стать очень сложно.

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

  • Я применил преобразование движения к parentView
  • Я применил преобразование вращения к первому подвиду parentViews;
  • Я применил преобразование масштаба к первому подвиду подвидов parentViews.

ИЗМЕНИТЬ

Хорошо, я перенастроил предоставленный пример кода, чтобы показать, как это возможно, чтобы оставить колесо в преобразованном положении:

(загрузите здесь обновленный пример кода: http://www.speedyshare.com/5d8Xq/download/Wheel-demo2.zip )

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

Итак, чтобы оставить его в перспективе, пока мы с ним взаимодействуем, нам нужен еще один слой просмотра.

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

Затем я применяю преобразование к родительскому представлению вместо колеса. И это работает!

Надеюсь, это помогло, и теперь вы понимаете больше о преобразованиях :)

person Guntis Treulands    schedule 16.10.2012
comment
В моем случае это не работает. У меня есть несколько небольших представлений, которые находятся вместе в одном представлении (как представление контейнера). Когда вы пытаетесь изменить перспективу, маленькое изображение отделяется друг от друга. Я также хотел, чтобы вращение или перспектива по другой оси. - person Aitul; 16.10.2012
comment
загрузите этот пример кода github.com/wczekalski/CDPieMenu представьте, что я хочу изменить перспективу на этот uiview CDPieMenu, как мне это сделать? - person Aitul; 16.10.2012
comment
Мне нравится ваш ответ, я знаю, как делать анимацию, но я хочу все время появляться с перспективой. а при выборе пункта хорошо продолжить с той же точки зрения. Я хочу, например, это колесо с перспективой 45 градусов. В оси x с перспективой и иметь возможность вращать колесо и продолжать с перспективой 45 градусов. - person Aitul; 16.10.2012
comment
в последнем ответе колесо не с перспективой. Я думаю, что перспектива должна быть сделана в методе - (void)drawRect:(CGRect)rect в классе CDCircleOverlayView или CDCircle или CDCircleOverlayView. Что вы думаете? - person Aitul; 16.10.2012
comment
Это с перспективой. Перспективу можно изменить, изменив параметр m34 и угол трансформации. (Проверьте крайнюю левую стрелку с крайней правой стрелкой. Один выглядит больше другого, поэтому он перспективный.) Также - установите цвет фона для родительского подвида, чтобы увидеть, что он на самом деле находится в перспективе. - person Guntis Treulands; 16.10.2012
comment
У вас есть опыт работы с этим образцом, легко ли избежать вращения в одном направлении? Я имею в виду, разрешить вращение этого колеса только в одном направлении - person Aitul; 16.10.2012
comment
Рад, что смог помочь :) Вы должны изучить - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - сохранить значение angleInRadians и сравнить его с ранее сохраненным перед настройкой преобразования, чтобы узнать, происходит ли оно в противоположном направлении или в правильном направлении (тогда соответственно разрешить или не разрешить трансформироваться). - person Guntis Treulands; 16.10.2012
comment
что вы имеете в виду, чтобы сравнить currentTransformAngle и angleInRadians. angleInRadians может быть положительным или отрицательным в обоих направлениях - person Aitul; 16.10.2012
comment
CGFloat angleInRadians = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, предыдущаяTouchPoint.x - center.x); Как я могу сравнить эти два значения, чтобы узнать предыдущее направление (первое и второе) CGFloat first = atan2f (currentTouchPoint.y - center.y, currentTouchPoint.x - center.x); CGFloat second =atan2f(предыдущийTouchPoint.y - center.y, предыдущийTouchPoint.x - center.x); currentTransformAngle = atan2f(view.transform.b, view.transform.a); - person Aitul; 16.10.2012
comment
Когда я сделал это: NSLog(@%f,angleInRadians); Выглядело так, что он всегда был отрицательным в одном направлении. Но после дальнейшего тестирования, похоже, мое предложение не сработает. Мне жаль. - person Guntis Treulands; 16.10.2012
comment
Я думаю, что метод, с помощью которого я могу это проверить, — это touchesMoved, но все значения, которые я получаю, когда пытаюсь двигаться в обоих направлениях, всегда разные. Любое предложение? - person Aitul; 16.10.2012
comment
Это не моя сильная сторона. Я бы предложил создать новый вопрос (чтобы привлечь больше людей), с той же ссылкой на проект, примером кода от touchesModed и вопросом — как разрешить трансформации только в одну сторону. Удачи! - person Guntis Treulands; 16.10.2012