在背景中绘图 [英] Drawing in the Background

查看:64
本文介绍了在背景中绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 IOS 应用程序,需要更新视图以响应用户或外部事件.绘制时间可以很短也可以很长(几秒钟),具体取决于视图中的内容.

I have an IOS application that needs to update a view in response to either user or external events. The drawing time can be either very short or very long (several seconds) depending upon what is in the view.

现在,绘图发生在视图的 drawRect 方法中.当绘图很长并且有大量用户交互时,应用会变得无响应.

Right now, the drawing takes place in the drawRect method for the view When the drawing is long and there is a lot of user interaction the app becomes unresponsive.

当它需要更新时,需要更新整个视图.如果在绘制过程中发生更改,则重新开始绘制以将更改考虑在内是有意义的.

When it needs updating, the entire view needs to be updated. If a change comes in the middle of drawing, it would make sense to restart the drawing to take into account the changes.

我想在后台进行绘图.

我的问题是在 IOS 中执行此操作的最佳机制是什么?

My question is what would be the best mechanism for doing this in IOS?

线程,NSOperation?

Thread, NSOperation?

我如何处理绘图?例如,如何在线程中获取我正在更新的视图的图形上下文?

How do I handle the drawing? For example, how do I get a graphics context in the thread for the view I am updating?

绘图操作应该如何启动?现在我正在做 setNeedsDisplay.我可以换做别的.

How should the drawing operation be kicked off? right now I am doing setNeedsDisplay. I could change to do something else.

有问题的视图位于 UIScrollView 中,但没有其他用户交互.

The view in question is within a UIScrollView but has no other user interaction.

推荐答案

这里是一个框架.代码假定输出视图是 UIImageView.后台任务使用位图内存上下文为输出视图创建新图像.当后台绘制任务完成后,主线程将生成的图像分配给 UIImageView.

Here's a framework to start with. The code assumes that the output view is a UIImageView. The background task uses a bitmapped memory context to create a new image for the output view. When the background drawing task completes, the main thread assigns the resulting image to the UIImageView.

sequenceNumber 用于在完成绘制之前丢弃已过期的图像.一个可能的问题是事件发生得太快,以至于每个图像在完成之前就已经过时了.解决这个问题留给读者作为练习.

The sequenceNumber is used to discard images that are out of date before they finish being drawn. One possible problem is that events arrive so quickly that every image is out of date before being finished. Solving that problem is left as an exercise for the reader.

@interface SomeClass()
@property (weak, nonatomic) IBOutlet UIImageView *someView;
@property (nonatomic) int64_t sequenceNumber;
@end

@implementation SomeClass

- (UIImage *)createImageUsingBitmapMemoryContextOfSize:(CGSize)size
{
    // create the memory bitmap context
    UIGraphicsBeginImageContext( size );
    CGContextRef context = UIGraphicsGetCurrentContext();

    // draw something
    [[UIColor blueColor] set];
    CGContextFillEllipseInRect( context, CGRectMake(0, 0, size.width, size.height) );

    // create a UIImage 
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // return the image
    return( result );
}

// Note: the following function should only be called on the main thread
- (void)updateInResponseToSomeEvent
{
    self.sequenceNumber++;
    int64_t sequenceNumber = self.sequenceNumber;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^
    {
        UIImage *image = [self createImageUsingBitmapMemoryContextOfSize:self.someView.bounds.size];
        dispatch_async( dispatch_get_main_queue(), ^
        {
            if ( sequenceNumber == self.sequenceNumber )
                self.someView.image = image;
        });
    });
}

这篇关于在背景中绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆