Вы должны установить свои собственные anchorPoint
Сильно излишне использовать анимацию ключевого кадра для того, что действительно является изменением точки привязки .
Точка привязки - это точка, к которой применяются все преобразования, точка привязки по умолчанию - центр. Переместив опорную точку в (0,0), вы можете вместо этого повернуть слой из самого нижнего угла. Установив точку привязки на что-то, где x или y находится вне диапазона 0,0 - 1,0, вы можете сделать так, чтобы слой вращался вокруг точки, которая находится за пределами его границ.
Пожалуйста, прочитайте раздел о Геометрия слоя и преобразования в Руководстве по программированию базовой анимации для получения дополнительной информации. Это подробно описано с помощью изображений, которые помогут вам понять.
РЕДАКТИРОВАТЬ: Одна вещь, чтобы помнить
кадр вашего слоя (который также является кадр вашего зрения) вычисляется с использованием позиции, оценки и точки привязки. Изменение anchorPoint изменит место, где ваш вид появится на экране. Вы можете противостоять этому, повторно установив рамку после изменения точки привязки (это будет установить позицию для вас). В противном случае вы можете установить положение в точку, которую вы вращаете для себя. В документации (ссылка выше) также упоминается об этом.
Приложенный к вам код
Точка, которую вы назвали «транспортной точкой», должна быть обновлена, чтобы вычислить разницу между точкой поворота и нижним левым углом метки, деленную на ширину и высоту.
// Pseudocode for the correct anchor point
transportPoint = ( (rotationX - labelMinX)/labelWidth,
(rotationX - labelMinY)/labelHeight )
Я также сделал точку вращения аргументом вашего метода. Полный обновленный код ниже:
#define DEGREES_TO_RADIANS(angle) (angle/180.0*M_PI)
- (void)rotateText:(UILabel *)label
aroundPoint:(CGPoint)rotationPoint
duration:(NSTimeInterval)duration
degrees:(CGFloat)degrees {
/* Setup the animation */
[UILabel beginAnimations:nil context:NULL];
[UILabel setAnimationDuration:duration];
// The anchor point is expressed in the unit coordinate
// system ((0,0) to (1,1)) of the label. Therefore the
// x and y difference must be divided by the width and
// height of the label (divide x difference by width and
// y difference by height).
CGPoint transportPoint = CGPointMake((rotationPoint.x - CGRectGetMinX(label.frame))/CGRectGetWidth(label.bounds),
(rotationPoint.y - CGRectGetMinY(label.frame))/CGRectGetHeight(label.bounds));
[label.layer setAnchorPoint:transportPoint];
[label.layer setPosition:rotationPoint]; // change the position here to keep the frame
[label.layer setTransform:CATransform3DMakeRotation(DEGREES_TO_RADIANS(degrees), 0, 0, 1)];
/* Commit the changes */
[UILabel commitAnimations];
}