Если пропеллер не вращается, это может произойти, если вы сразу не добавили это view
в иерархию вида. Как правило, целесообразно добавить представление в иерархию представлений до вас addAnimation
.
- (UIView *)addPropellerToView:(UIView *)view {
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 37, 37)];
// make sure to add it to the view hierarchy
[view addSubview:containerView];
// if you want to center it, set its `center` to be in the middle of the `bounds` ... don't use `center`
containerView.center = CGPointMake(view.bounds.origin.x + view.bounds.size.width / 2, view.bounds.origin.y + view.bounds.size.height / 2);
// I'd just use the `bounds` of the container view; reducing the risk that we get its coordinates wrong
UIImageView *movablePropeller = [[UIImageView alloc] initWithFrame:containerView.bounds];
movablePropeller.image = [UIImage imageNamed:@"MovablePropeller"];
movablePropeller.contentMode = UIViewContentModeScaleAspectFill;
[containerView addSubview:movablePropeller];
// never set the center of a view to the center of its super view ... those are two different coordinate systems.
// in this case, this line isn't needed at all, so I'll remove it.
//
// movablePropeller.center = containerView.center;
CABasicAnimation *rotation;
rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotation.fromValue = @(0);
rotation.toValue = @(2 * M_PI);
rotation.cumulative = true;
rotation.duration = 1.2f;
rotation.repeatCount = INFINITY;
[movablePropeller.layer addAnimation:rotation forKey:@"Spin"];
return containerView;
}
Выход:
Некоторые несвязанные наблюдения:
Если вы хотите центрировать вид A в середине вида B, установите для вида A center
координаты к средней точке B bounds
, а не B center
. Например, вы никогда не хотите делать:
A.center = B.center;
То, что вы хотите, это:
A.center = CGPointMake(B.bounds.origin.x + B.bounds.size.width / 2, B.bounds.origin.y + B.bounds.size.height / 2);
Я знаю, похоже, что это должно быть то же самое, но это не так. center
определяется, как frame
, в системе координат B. Но B center
определяется в системе координат его суперпредставления, , которое может быть совершенно другим. Иногда вы не заметите разницу (в частности, если B origin
равен {0, 0}
), но это предполагает неправильное понимание различных систем координат, а если B не равно {0, 0}
, то все будет неправильно.
Вы можете использовать NSNumber
литералы, заменив [NSNumber numberWithFloat:0.0f]
на @(0)
.
Вам действительно не нужен этот вид контейнера, поэтому вы можете упростить процедуру, как показано ниже.
- (UIView *)addPropellerTo:(UIView *)view {
UIImageView *movablePropeller = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 37, 37)];
movablePropeller.image = [UIImage imageNamed:@"MovablePropeller"];
movablePropeller.contentMode = UIViewContentModeScaleAspectFill;
[view addSubview:movablePropeller];
movablePropeller.center = CGPointMake(view.bounds.origin.x + view.bounds.size.width / 2, view.bounds.origin.y + view.bounds.size.height / 2);
CABasicAnimation *rotation;
rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotation.fromValue = @(0);
rotation.toValue = @(2 * M_PI);
rotation.cumulative = true;
rotation.duration = 1.2f;
rotation.repeatCount = INFINITY;
[movablePropeller.layer addAnimation:rotation forKey:@"Spin"];
return movablePropeller;
}