snapshotViewAfterScreenUpdates creating a blank image

时光总嘲笑我的痴心妄想 提交于 2019-12-11 02:58:15

问题


I'm trying to create some composite UIImage objects with this code:

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;
}

I just get back a blank black image. How can I fix?


回答1:


Supplying YES for -snapshotViewAfterScreenUpdates: means it needs a trip back to the runloop to actually draw the image. If you supply NO, it will try immediately, but if your view is off screen or otherwise hasn't yet drawn to the screen, the snapshot will be empty.

To reliably get an image:

- (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]);
        }
    });
}

You would use it like this:

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



回答2:


The snapshotted view has to be drawn to the screen for a snapshot view to not be blank. In your case, the composite view must have a superview for drawing to work.

However, you should not be using the snapshotting API for this kind of action. It is very inefficient to create a view hierarchy for the sole purpose of creating an image. Instead, use the Core Graphics API's to setup a bitmap image context, perform drawing and get back the result using UIGraphicsGetImageFromCurrentImageContext().




回答3:


The reason it's only rendering a black rectangle is because you're drawing the view hierarchy of the snapshot view, which is non-existent.

To make it work, you should pass composite as the parameter like so:

- (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;

}



来源:https://stackoverflow.com/questions/27913285/snapshotviewafterscreenupdates-creating-a-blank-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!