【问题标题】:snapshotViewAfterScreenUpdates creating a blank imagesnapshotView AfterScreenUpdates 创建一个空白图像
【发布时间】:2023-03-31 06:15:02
【问题描述】:

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

someImageView.image = [ImageMaker coolImage];

图像制作者:

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

我刚刚得到一张空白的黑色图像。我该如何解决?

【问题讨论】:

    标签: ios uiview uiimageview uiimage


    【解决方案1】:

    -snapshotViewAfterScreenUpdates: 提供YES 意味着它需要返回运行循环才能实际绘制图像。如果您提供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];
    }];
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        为了让它工作,你应该像这样传递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;
        
        }
        

        【讨论】:

          猜你喜欢
          • 2018-04-11
          • 2018-03-08
          • 1970-01-01
          • 2017-03-01
          • 2017-01-23
          • 2012-06-05
          • 2020-05-02
          • 2011-06-07
          • 2011-08-29
          相关资源
          最近更新 更多