snapshotViewAfterScreenUpdates创建空白图像

我正在尝试使用以下代码创建一些复合UIImage对象:

someImageView.image = [ImageMaker coolImage]; 

ImageMaker:

 - (UIImage*)coolImage { UIView *composite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)]; UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"coolImage"]]; //This is a valid image - can be viewed when debugger stops here [composite addSubview:imgView]; UIView *snapshotView = [composite snapshotViewAfterScreenUpdates:YES]; //at this point snapshotView is just a blank image UIImage *img = [self imageFromView:snapshotView]; return img; } - (UIImage *)imageFromView:(UIView *)view { UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0.0); [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; } 

我刚刚拿回一张空白的黑色图片。 我该怎么办?

-snapshotViewAfterScreenUpdates:提供YES -snapshotViewAfterScreenUpdates:意味着它需要返回runloop才能实际绘制图像。 如果您提供NO ,它将立即尝试,但如果您的视图在屏幕外或尚未绘制到屏幕上,则快照将为空。

要可靠地获取图像:

 - (void)withCoolImage:(void (^)(UIImage *))block { UIView *composite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)]; UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"coolImage"]]; //This is a valid image - can be viewed when debugger stops here [composite addSubview:imgView]; UIView *snapshotView = [composite snapshotViewAfterScreenUpdates:YES]; // give it a chance to update the screen… dispatch_async(dispatch_get_main_queue(), ^ { // … and now it'll be a valid snapshot in here if(block) { block([self imageFromView:snapshotView]); } }); } 

你会像这样使用它:

 [someObject withCoolImage:^(UIImage *image){ [self doSomethingWithImage:image]; }]; 

必须将快照视图绘制到屏幕上,以使快照视图不为空白。 在您的情况下,复合视图必须具有用于绘图才能工作的超级视图。

但是,您不应该使用快照API进行此类操作。 仅为创建图像而创建视图层次结构效率非常低。 相反,使用Core Graphics API设置位图图像上下文,执行绘图并使用UIGraphicsGetImageFromCurrentImageContext()获取结果。

它只渲染黑色矩形的原因是因为您正在绘制快照视图的视图层次结构,这是不存在的。

要使其工作,您应该将composite作为参数传递,如下所示:

 - (UIImage*)coolImage { UIView *composite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)]; UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"coolImage"]] [composite addSubview:imgView]; UIImage *img = [self imageFromView:composite]; // Uncomment if you don't want composite to have imgView as its subview // [imgView removeFromSuperview]; return img; } 

之前

结果