UIImageView 在 for 循环中不更新图像
UIImageView doesn't update image while in for loop
我有一个 CGRect 数组 arr
,我想在 for 循环中将这些矩形绘制到图像上。这是代码:
__block UIImage *procImage=image;
for(int i=0;i<arr.count;i++){
CGRect rect=[[arr objectAtIndex:i] CGRectValue];
procImage=[self drawText:[NSString stringWithFormat:@"%d",i] inImage:procImage atPoint:CGPointMake(rect.origin.x,rect.origin.y-rect.size.height) withRect:rect];
[self.imageView setImage:procImage];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
procImage=[self drawText:[NSString stringWithFormat:@"%d",i] inImage:procImage atPoint:CGPointMake(rect.origin.x,rect.origin.y-rect.size.height) withRect:rect];
[self.imageView setImage:procImage];
}];
}
这是drawText:
函数
-(UIImage*) drawText:(NSString*) text
inImage:(UIImage*) image
atPoint:(CGPoint) point
withRect:(CGRect)rectangle
{
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[text drawInRect:CGRectIntegral(rect) withAttributes:@{NSForegroundColorAttributeName: [UIColor greenColor],
NSFontAttributeName:[UIFont boldSystemFontOfSize:50]}
];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextStrokeRect(context, rectangle);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
问题是 imageView 只在 for 循环结束时更新它的图像。我想创建一个漂亮的动画,每次在 for 循环期间绘制一个新矩形时都会更新图像。
编辑
我简化了代码。就我而言,我正在为每个文本块执行 OCR 过程,因此这会花费很多时间(可能是几分钟)。在那段时间里,我想向用户展示一些过程,而不是每次完成文本块时的死界面。
不清楚您要达到的效果。您是否希望在其目标矩形中绘制每个图像和文本之间有一个短暂的延迟,以便它们堆叠起来?
你有2个问题。首先,在您的代码 return 之前,没有任何内容真正呈现到屏幕上。因此,当你 运行 一个这样的循环时,绘图调用只是堆叠起来,你 return 来自你的代码,然后所有内容都会呈现到屏幕上。
即使您解决了这个问题,您的第二个问题是在屏幕上绘制一幅又一幅图像的速度太快,以至于用户的眼睛看不到各个步骤。
如果我对您尝试做的事情的看法是正确的,您可以改用这种方式。
添加一个实例变量来跟踪当前图像的索引。将其设置为零。
编写一个方法,在当前矩形绘制当前图像和文本,然后递增索引实例变量。如果 images/rectangles 数组中有更多条目,请在短暂延迟后使用 GCD 调用 dispatch_after 在主线程上调用该方法。这将 return 控制主线程并让新绘图呈现到屏幕上,并让用户有时间在绘制下一个绘图之前查看该绘图。
编辑:
正如@Paulw11 在他的评论中所说,您还可以使用重复计时器重新调用您的方法,并在数组中的条目 运行 不足时简单地使其无效。
创建您的图像数组并缓存它。然后使用 UIImageView
animationImages
属性 存储您创建的图像数组并让 UIImageView
处理动画。每次构建图像都是过程密集型的。
Apple 文档:
我有一个 CGRect 数组 arr
,我想在 for 循环中将这些矩形绘制到图像上。这是代码:
__block UIImage *procImage=image;
for(int i=0;i<arr.count;i++){
CGRect rect=[[arr objectAtIndex:i] CGRectValue];
procImage=[self drawText:[NSString stringWithFormat:@"%d",i] inImage:procImage atPoint:CGPointMake(rect.origin.x,rect.origin.y-rect.size.height) withRect:rect];
[self.imageView setImage:procImage];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
procImage=[self drawText:[NSString stringWithFormat:@"%d",i] inImage:procImage atPoint:CGPointMake(rect.origin.x,rect.origin.y-rect.size.height) withRect:rect];
[self.imageView setImage:procImage];
}];
}
这是drawText:
函数
-(UIImage*) drawText:(NSString*) text
inImage:(UIImage*) image
atPoint:(CGPoint) point
withRect:(CGRect)rectangle
{
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[text drawInRect:CGRectIntegral(rect) withAttributes:@{NSForegroundColorAttributeName: [UIColor greenColor],
NSFontAttributeName:[UIFont boldSystemFontOfSize:50]}
];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextStrokeRect(context, rectangle);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
问题是 imageView 只在 for 循环结束时更新它的图像。我想创建一个漂亮的动画,每次在 for 循环期间绘制一个新矩形时都会更新图像。
编辑
我简化了代码。就我而言,我正在为每个文本块执行 OCR 过程,因此这会花费很多时间(可能是几分钟)。在那段时间里,我想向用户展示一些过程,而不是每次完成文本块时的死界面。
不清楚您要达到的效果。您是否希望在其目标矩形中绘制每个图像和文本之间有一个短暂的延迟,以便它们堆叠起来?
你有2个问题。首先,在您的代码 return 之前,没有任何内容真正呈现到屏幕上。因此,当你 运行 一个这样的循环时,绘图调用只是堆叠起来,你 return 来自你的代码,然后所有内容都会呈现到屏幕上。
即使您解决了这个问题,您的第二个问题是在屏幕上绘制一幅又一幅图像的速度太快,以至于用户的眼睛看不到各个步骤。
如果我对您尝试做的事情的看法是正确的,您可以改用这种方式。
添加一个实例变量来跟踪当前图像的索引。将其设置为零。
编写一个方法,在当前矩形绘制当前图像和文本,然后递增索引实例变量。如果 images/rectangles 数组中有更多条目,请在短暂延迟后使用 GCD 调用 dispatch_after 在主线程上调用该方法。这将 return 控制主线程并让新绘图呈现到屏幕上,并让用户有时间在绘制下一个绘图之前查看该绘图。
编辑:
正如@Paulw11 在他的评论中所说,您还可以使用重复计时器重新调用您的方法,并在数组中的条目 运行 不足时简单地使其无效。
创建您的图像数组并缓存它。然后使用 UIImageView
animationImages
属性 存储您创建的图像数组并让 UIImageView
处理动画。每次构建图像都是过程密集型的。
Apple 文档: