如何实施像天气频道iOS应用中的加载动画?
具体来说,我有一个四舍五入的UIButton
,当用户点击它时,我想要一个旋转的圆圈,并且正在加载。
最好,我希望使用内置的iOS框架,尽可能少的第三方库。
以下是天气频道应用程序的外观(无法获取gif,因此要查看它在运行中从App Store下载应用程序):
它不一定非常像这样,纯色将是一个良好的开端。但这个概念应该是一样的。我不相信它应该很难制作,但遗憾的是我不知道从哪里开始。
感谢您的帮助!
编辑1: 我应该指出,纯色足够好,并且它不需要渐变或发光。
我一直在研究一些可能正确方向的简单代码。请随意使用它作为起点:
- (void)drawRect:(CGRect)rect {
// Make the button round
self.layer.cornerRadius = self.frame.size.width / 2.0;
self.clipsToBounds = YES;
// Create the arc
CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2) radius:(self.frame.size.width / 2) startAngle:M_PI_2 endAngle:M_PI clockwise:NO].CGPath;
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor redColor].CGColor;
circle.lineWidth = 10;
// Create the animation
// Add arc to button
[self.layer addSublayer:circle];
}
答案 0 :(得分:2)
正如其他地方所指出的,你可以添加一个视图,然后旋转它。如果要使用基于块的动画旋转,它可能如下所示:
- (void)rotateView:(UIView *)view {
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:UIViewKeyframeAnimationOptionRepeat animations:^{
for (NSInteger i = 0; i < 4; i++) {
[UIView addKeyframeWithRelativeStartTime:(CGFloat) i / 4.0 relativeDuration:0.25 animations:^{
view.transform = CGAffineTransformMakeRotation((CGFloat) (i + 1) * M_PI / 2.0);
}];
}
} completion:nil];
} completion:nil];
}
坦率地说,虽然我通常更喜欢基于块的动画,但是用动画包装动画的愚蠢(这是不容易进入/放松的必要条件)使得基于块的方法不那么引人注目。但它说明了这个想法。
或者,在iOS 7及更高版本中,您可以使用UIKit Dynamics来旋转它:
为动画师定义属性:
@property (nonatomic, strong) UIDynamicAnimator *animator;
实例化动画师:
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
向项目添加轮播:
UIDynamicItemBehavior *rotationBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.imageView]];
[rotationBehavior addAngularVelocity:2.0 forItem:self.imageView];
[self.animator addBehavior:rotationBehavior];
答案 1 :(得分:1)
也许我想念一些东西,但我认为你只需要旋转自定义旋转资产。
您可以使用以下方法轻松实现此目的:
- (void) runSpinAnimationOnView:(UIView*)view duration:(CGFloat)duration repeat:(float)repeat;
{
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 * duration ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = repeat;
[view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
你需要无限期地重复它。所以把HUGE_VALF
作为重复参数。
如果您想根据按钮大小创建自定义旋转图像,则可以使用bezier路径。例如,您可以执行以下操作:
-(UIImageView*)drawBezierPathInView:(UIView*)view{
UIGraphicsBeginImageContext(CGSizeMake(view.frame.size.width, view.frame.size.height));
//this gets the graphic context
CGContextRef context = UIGraphicsGetCurrentContext();
//you can stroke and/or fill
CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0.5f green:0.5f blue:0.5f alpha:1.f].CGColor);
CGFloat lineWidth = 8.f;
UIBezierPath *spin = [UIBezierPath bezierPath];
[spin addArcWithCenter:CGPointMake(view.frame.size.width * 0.5f, view.frame.size.height * 0.5f) radius:view.frame.size.width * 0.5f - lineWidth * 0.5f startAngle:-M_PI_2 endAngle:2 * M_PI_2 clockwise:YES];
[spin setLineWidth:lineWidth];
[spin stroke];
//now get the image from the context
UIImage *bezierImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *bezierImageView = [[UIImageView alloc]initWithImage:bezierImage];
return bezierImageView;
}
然后创建按钮,如:
// myButton is your custom button. spinView is an UIImageView, you keep reference on it to apply or to stop animation
self.spinView = [self drawBezierPathInView:mybutton];
[mybutton addSubview:self.spinView];
[self runSpinAnimationOnView:self.spinView duration:3 repeat:HUGE_VALF];