iPhone 圆形进度指示器。 CGContextRef。按需提款
我想绘制一个图像,该图像实际上是 UIButton 上的圆形进度指示器。因为图像应该代表任务的进度,所以我认为我不应该在视图的drawrect 方法中处理绘图代码。
我有一个正在执行一些任务的线程。每个任务完成后,它都会调用主线程上的一个方法。被调用的方法应该更新按钮上的图像。
在按钮更新方法中,我使用 CGBitmapContextCreate 创建 CGContextRef。 然后我使用按钮的框架创建一个 CGRect。 然后我尝试使用我创建的上下文。 最后我设置 NeedsDisplay 并清理。
但这些都不在视图的drawrect 方法中。
我想知道是否有人在显示视图时使用 CGContext 在视图中按需绘制/在视图中绘制。
我想获得一些关于执行此操作的方法的想法。
这是我现在正在做的事情的封装版本: CGContextRef xContext = nil; CGColorSpaceRef xColorSpace; CG矩形x矩形; 无效* xBitmapData; int iBMPByteCount; int iBMPBytesPerRow; 浮动fBMP宽度= 20.0f; 浮动fBMMPHeight = 20.0f; 浮动 fPI = 3.14159; 浮动 fRadius = 25.0f;
iBMPBytesPerRow = (fBMPWidth * 4);
iBMPByteCount = (iBMPBytesPerRow * fBMPHeight);
xColorSpace = CGColorSpaceCreateDeviceRGB();
xBitmapData = malloc(iBMPByteCount);
xContext = CGBitmapContextCreate(xBitmapData, fBMPWidth, fBMPHeight, 8, iBMPBytesPerRow, xColorSpace, kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(xColorSpace);
UIGraphicsPushContext(xContext);
xRect = CGRectMake(30.0f, 400.0f, 50.0f, 50.0f);
float fWidth = xRect.size.width;
float fHeight = xRect.size.height;
CGContextClearRect(xContext, xRect);
CGContextSetRGBStrokeColor(xContext, 0.5f, 0.6f, 0.7f, 1.0f);
CGContextSetLineWidth(xContext, 1.0f);
float fArcBegin = 45.0f * fPI / 180.0f;
float fArcEnd = 90.0f * fPI / 180.0f;
CGContextSetFillColor(xContext, CGColorGetComponents( [[UIColor greenColor] CGColor]));
CGContextMoveToPoint(xContext, fWidth, fHeight);
CGContextAddArc(xContext, fWidth, fHeight, fRadius, fArcBegin, fArcEnd, 0);
CGContextClosePath(xContext);
CGContextFillPath(xContext);
UIGraphicsPopContext;
CGContextRelease(xContext);
[self.view setNeedsDisplay];
// [self.view setNeedsDisplayInRect: xRect];
上面的内容有点奇怪,因为我尝试过不同的调整。然而,我认为它传达了我正在尝试做的事情。
I want to draw an image that would effectively be a circular progress indicator on a UIButton. Because the image is supposed to represent progress of a task, I do not think I should handle the drawing code in the view's drawrect method.
I have a thread that is performing some tasks. After each task, it calls a method on the main thread. The called method is supposed to update the image on the button.
In the button update method, I create a CGContextRef by using CGBitmapContextCreate.
Then I use the button's frame to create a CGRect.
Then I attempt to draw into using the context I created.
Lastly I set NeedsDisplay and clean up.
But none of this is inside the view's drawrect method.
I would like to know if anyone has used CGContext to draw on / in a view on-demand in a view while the view is being displayed.
I would like to get some ideas regarding an approach to doing this.
Here is an encapsulated version of what I am doing now:
CGContextRef xContext = nil;
CGColorSpaceRef xColorSpace;
CGRect xRect;
void* xBitmapData;
int iBMPByteCount;
int iBMPBytesPerRow;
float fBMPWidth = 20.0f;
float fBMPHeight = 20.0f;
float fPI = 3.14159;
float fRadius = 25.0f;
iBMPBytesPerRow = (fBMPWidth * 4);
iBMPByteCount = (iBMPBytesPerRow * fBMPHeight);
xColorSpace = CGColorSpaceCreateDeviceRGB();
xBitmapData = malloc(iBMPByteCount);
xContext = CGBitmapContextCreate(xBitmapData, fBMPWidth, fBMPHeight, 8, iBMPBytesPerRow, xColorSpace, kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(xColorSpace);
UIGraphicsPushContext(xContext);
xRect = CGRectMake(30.0f, 400.0f, 50.0f, 50.0f);
float fWidth = xRect.size.width;
float fHeight = xRect.size.height;
CGContextClearRect(xContext, xRect);
CGContextSetRGBStrokeColor(xContext, 0.5f, 0.6f, 0.7f, 1.0f);
CGContextSetLineWidth(xContext, 1.0f);
float fArcBegin = 45.0f * fPI / 180.0f;
float fArcEnd = 90.0f * fPI / 180.0f;
CGContextSetFillColor(xContext, CGColorGetComponents( [[UIColor greenColor] CGColor]));
CGContextMoveToPoint(xContext, fWidth, fHeight);
CGContextAddArc(xContext, fWidth, fHeight, fRadius, fArcBegin, fArcEnd, 0);
CGContextClosePath(xContext);
CGContextFillPath(xContext);
UIGraphicsPopContext;
CGContextRelease(xContext);
[self.view setNeedsDisplay];
// [self.view setNeedsDisplayInRect: xRect];
The above is a little bit wonky because I've tried different tweaks. However, I think it communicates what I am trying to do.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
替代方法:
您可以创建一系列表示进度更新的图像,然后在流程的每个步骤将 UIButton currentImage 属性替换为 setImage:forState: 方法。这不需要在现有视图中绘制,并且这种方法对我来说非常有效,可以显示图像(按钮或其他)的简单“动画”。
这种方法对你有用吗?如果没有,为什么不呢?
巴特
Alternative approach:
You could create a series of images that represent the progress updates and then replace the UIButton currentImage property with the setImage:forState: method at each step of the process. This doesn't require drawing in the existing view and this approach has worked well for me to show simple "animation" of images (buttons or other).
Would this approach work for you? If not, why not?
Bart
这真的让我很烦恼,所以在处理了一系列关于我想要这个功能的项目的愚蠢但必要的问题之后,我开始尝试它。
最终结果是,我现在可以任意绘制一条弧线,表示按钮上特定后台任务的进度。
目标是在清理或编译项目时在 XCode 窗口右下角绘制类似小指示器的内容。
我创建了一个函数,它将绘制并填充圆弧并将其作为 UIImage 返回。
工作线程使用当前值和按钮标识符调用方法 (PerformSelectorOnMainThread)。在被调用的方法中,我调用圆弧图像函数并填充百分比等。
调用示例:
然后设置按钮的背景图片:
函数如下:
它尚未完成,但它的效果足以说明我是如何做到这一点的。
This was really bugging me so after dealing with a series of silly, but necessary issues regarding the project I want this functionality for, I played around with it.
The end result is that I can now arbitrarily draw an arc representing the progress of a particular background task to a button.
The goal was to draw something like the little indicator in the lower right hand corner of the XCode windows while a project is being cleaned or compiled.
I created a function that will draw and fill an arc and return it as a UIImage.
The worker thread calls method (PerformSelectorOnMainThread) with the current values and a button identifier. In the called method, I call the arc image function with the percentage filled and such.
example call:
Then set the background image of the button:
Here is the function:
It is not finished, but it works well enough to illustrate how I am doing this.