【发布时间】:2017-06-30 18:12:23
【问题描述】:
编辑:我认为最好的是将代码转换为CoreAnimation。如何将此代码转换为该方法?我认为问题在于设备 FPS 存在差异。
我一直在寻找 iOS 的自定义进度圈,偶然发现了这个库:https://github.com/Eclair/CircleProgressBar
然而,我注意到每当动画超过 5 秒时都会出现错误。圆圈的动画比它应该的要慢。例如:我将圆圈设置为在 30 秒内完成 100% 的动画,但在该时间段内仅达到 78% (“完成”标签在 30 秒的 NSTimer 后可见)。查看我在制作的演示项目中拍摄的这张图片:
这是制作圆圈的代码:
- (void)drawProgressBar:(CGContextRef)context progressAngle:(CGFloat)progressAngle center:(CGPoint)center radius:(CGFloat)radius {
CGFloat barWidth = self.progressBarWidthForDrawing;
if (barWidth > radius) {
barWidth = radius;
}
CGContextSetFillColorWithColor(context, self.progressBarProgressColorForDrawing.CGColor);
CGContextBeginPath(context);
CGContextAddArc(context, center.x, center.y, radius, DEGREES_TO_RADIANS(_startAngle), DEGREES_TO_RADIANS(progressAngle), 0);
CGContextAddArc(context, center.x, center.y, radius - barWidth, DEGREES_TO_RADIANS(progressAngle), DEGREES_TO_RADIANS(_startAngle), 1);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextSetFillColorWithColor(context, self.progressBarTrackColorForDrawing.CGColor);
CGContextBeginPath(context);
CGContextAddArc(context, center.x, center.y, radius, DEGREES_TO_RADIANS(progressAngle), DEGREES_TO_RADIANS(_startAngle + 360), 0);
CGContextAddArc(context, center.x, center.y, radius - barWidth, DEGREES_TO_RADIANS(_startAngle + 360), DEGREES_TO_RADIANS(progressAngle), 1);
CGContextClosePath(context);
CGContextFillPath(context);
}
这是动画圆的代码:
- (void)animateProgressBarChangeFrom:(CGFloat)startProgress to:(CGFloat)endProgress duration:(CGFloat)duration {
_currentAnimationProgress = _startProgress = startProgress;
_endProgress = endProgress;
_animationProgressStep = (_endProgress - _startProgress) * AnimationChangeTimeStep / duration;
_animationTimer = [NSTimer scheduledTimerWithTimeInterval:AnimationChangeTimeStep target:self selector:@selector(updateProgressBarForAnimation) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSRunLoopCommonModes];
}
- (void)updateProgressBarForAnimation {
_currentAnimationProgress += _animationProgressStep;
_progress = _currentAnimationProgress;
if ((_animationProgressStep > 0 && _currentAnimationProgress >= _endProgress) || (_animationProgressStep < 0 && _currentAnimationProgress <= _endProgress)) {
[_animationTimer invalidate];
_animationTimer = nil;
_progress = _endProgress;
}
[self setNeedsDisplay];
}
这里有什么看起来不对的地方吗?有没有更好的方法来为圆圈设置动画?理想情况下,我希望它以正确的持续时间制作动画,但我对如何解决这个问题并不熟悉。
演示项目来展示问题: https://ufile.io/8pkt5
【问题讨论】:
-
我刚刚抓住了“Eclair/CircleProgressBar”存储库,将“增加”按钮更改为在 30 秒内直接达到 100% -
[_circleProgressBar setProgress:1.0f animated:YES duration:30.0];- 效果很好。你做了什么不同的事情吗? -
@DonMag 问题不在于它达到 100%,问题在于它实际上需要超过 30 秒。我会在一分钟内附上一个演示项目来展示这个问题。编辑:添加链接
-
嗯...我下载了您编辑的项目...在模拟器上运行它...观看它并在物理时钟上计时...“完成”标签在 100 处弹出%,在物理时钟上正好是 30 秒。然后在物理 7+ 上构建并运行它...相同(正确)的结果。
-
@DonMag 您正在运行哪个 iOS 版本和 MacOS 版本?我刚刚在 iOS 10.2.2 iPhone 6 Plus 上重新运行了示例项目,但我仍然看到了这个问题。我什至在我旁边运行了一个计时器来仔细检查并发现问题发生了。
-
我无法想象这是由于版本差异,但是... iMac 运行 El Cap 10.11.6 Simulator @ 10.2、Xcode 8.2.1、iPhone 7+ 10.2.1、iPad Air 10.2。 1 .. 只是为了它在 Sim iPhone 6 @ 9.3 上运行(需要少量代码编辑)......所有结果都一致,准确。
标签: ios animation core-graphics duration