Вращающееся колесо с этикетками - как держать этикетки в горизонтальном положении при вращении колеса?
Я искал решение о том, как реализовать колесо типа фортуны (работающее хорошо), за исключением того, что мне нужны изображения / метки на периферии колеса, чтобы они оставались горизонтальными и не вращались вместе с колесом. Я реализовал следующее, но метки (в данном случае красные овалы) не остаются горизонтальными.
Я прилагаю свой код, который строит красные овалы на экране:
CGFloat cita = 0;
for(int i = 1; i < 2; ++i)
{
CGFloat smallCircleRadius = bigCircleRadius / 8.0;
for (int i = 0; i < 8; i++)
{
CGPoint smallCircleCenter = CGPointMake(wheelCenter.x + bigCircleRadius * cos(cita) - smallCircleRadius/2.0 , wheelCenter.y + bigCircleRadius * sin(cita) - smallCircleRadius / 2.0 );
CGRect smallCircleRect = CGRectMake(smallCircleCenter.x,smallCircleCenter.y,smallCircleRadius * 2,smallCircleRadius);
cita += M_PI / 4.0;
CAShapeLayer *l = [CAShapeLayer layer];
UIBezierPath * p1 = [UIBezierPath bezierPathWithOvalInRect:smallCircleRect];
l.path = p1.CGPath;
l.strokeColor = [[UIColor redColor] CGColor];
l.fillColor = [[UIColor redColor] CGColor];
l.lineWidth = 3.0;
l.anchorPoint = CGPointMake(.5, .5);
[self.emoticonsArray addObject:l];
[self.baseWheel.layer addSublayer:l];
}
}
Ниже приведена функция, которая вращает колесо; Я делаю строку кода, которая выполняет вращение для меток - я, очевидно, здесь что-то делаю не так, но я понятия не имею, что. Любое руководство с благодарностью.
-(void)spin:(double)delta
{
currentAngle = currentAngle + delta;
CATransform3D transform = CATransform3DMakeRotation(currentAngle, 0, 0, 1);
[self.baseWheel.layer setTransform:transform];
// rotate the red labels here.
for (CAShapeLayer * l in self.emoticonsArray)
{
CGPoint miniWheelCenter = [l convertPoint:l.position toLayer:self.baseWheel.layer.superlayer];
// !! something wrong here!! but what?
CATransform3D t_l = CATransform3DMakeRotation(-currentAngle, miniWheelCenter.x/2, miniWheelCenter.y/2, 1);
[l setTransform:t_l];
}
}
3 ответа
Аргументы CATransform3DMakeRotation
угол и три составляющие оси вращения. Ось вращения как для колеса, так и для подслоев надписей должна быть просто осью Z. Вы получили это право на колесо, но не на этикетки.
CATransform3D t_l = CATransform3DMakeRotation(-currentAngle, 0, 0, 1);
[l setTransform:t_l];
Однако было бы проще использовать аффинные преобразования, которые могут вращаться только вокруг оси Z:
-(void)spin:(double)delta {
currentAngle = currentAngle + delta;
self.baseWheel.layer.affineTransform = CGAffineTransformMakeRotation(currentAngle);
CGAffineTransform labelTransform = CGAffineTransformMakeRotation(-currentAngle);
for (CAShapeLayer *l in self.emoticonsArray) {
l.affineTransform = labelTransform;
}
}
Core Animation преобразует аффинные преобразования в трехмерные преобразования для вас.
Другой способ избавиться от этой проблемы - не использовать метки в качестве подвида колеса. Вы просто помещаете их сверху колеса. Поэтому, когда колесо вращается, ярлыки будут на том же месте. Дайте мне знать, если я не достаточно ясно
РЕДАКТИРОВАТЬ
Вот альтернативное решение для вашей проблемы. Это не идеально, но может дать вам новое направление мышления.
- Возьмите свое изображение колеса в формате PNG.
- сделайте фон прозрачным для вашего колеса. (Не нужно.. просто чтобы украсить)
- сделайте отверстие в тех местах на колесе, где вы хотите показать метку. (Под отверстием я хотел сделать часть прозрачной).
- Теперь поместите метки за руль. Поместите их в соответствии с необходимым углом поворота.
- Теперь, когда вы поворачиваете колесо под точными углами, вы сможете видеть метки. Это как два слоя бумаги.
Почему это не Perfect Labels не будет двигаться с колесом. Таким образом, вы сможете видеть метки только под определенными углами.
Я не знаю точную цель требования вашего вопроса, но я использовал этот подход для создания Jog dial для своего приложения.
Проблема в том, что вы вращаете все колесо, для которого эти метки являются subViews.so, а также колесо, которое они также вращают.
Наилучшим подходом является вычисление значения угла поворота. Из этого угла рассчитайте новые позиции меток на этом круге и поместите метки (не подколесные колеса) в эти новые позиции.
ИЛИ (метод 2)
установите отрицание этого преобразования вращения на эти метки.