Это было слишком мило, чтобы отказаться, так что вот оно. Этот код ограничен вращением одной кнопки, но я сомневаюсь, что у вас будут проблемы с его расширением, чтобы взять несколько (подсказка: используйте ОДИН CADisplayLink и поверните все кнопки одновременно).
- (void)setupRotatingButtons
{
// call this method once; make sure "self.view" is not nil or the button
// won't appear. the below variables are needed in the @interface.
// center: the center of rotation
// radius: the radius
// time: a CGFloat that determines where in the cycle the button is located at
// (note: it will keep increasing indefinitely; you need to use
// modulus to find a meaningful value for the current position, if
// needed)
// speed: the speed of the rotation, where 2 * M_PI is 1 lap a second
// b: the UIButton
center = CGPointMake(100, 100);
radius = 100;
time = 0;
speed = 2 * M_PI; // <-- will rotate CW 360 degrees per second (1 "lap"/s)
b = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
b.titleLabel.text = @"Hi";
b.frame = CGRectMake(0.f, 0.f, 100, 50);
// we get the center set right before we add subview, to avoid glitch at start
[self continueCircling:nil];
[self.view addSubview:b];
[self.view bringSubviewToFront:b];
CADisplayLink *dl = [CADisplayLink displayLinkWithTarget:self
selector:@selector(continueCircling:)];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
Нам также нужен фактический метод continueCircling: просто:
- (void)continueCircling:(CADisplayLink *)dl
{
time += speed * dl.duration;
b.center = CGPointMake(center.x + radius * cosf(time),
center.y + radius * sinf(time));
}
Я уверен, что есть и другие, более изящные способы решения этой проблемы, но, по крайней мере, вышесказанное работает. :)
Редактировать: я забыл упомянуть, вам нужно будет добавить платформу QuartzCore и
#import <QuartzCore/QuartzCore.h>
для CADisplayLink.
Редактировать 2: Нашел постоянную PI (M_PI
), поэтому заменил на нее 3.1415.