【问题标题】:view.layer drawInContext:UIGraphicsGetCurrentContext() not drawingview.layer drawInContext:UIGraphicsGetCurrentContext() 不绘图
【发布时间】:2014-03-09 19:17:37
【问题描述】:

我正在尝试将UIView 绘制成UIImage。这是我正在使用的代码:

UIGraphicsBeginImageContextWithOptions(myView.bounds.size, YES, 0.f);
[myView.layer drawInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

我已验证 myView.bounds.size 有效。 myView 在屏幕上正确显示。但是,img 完全是黑色的(我尝试在 UIImageView 中同时显示并尝试将 JPEG 表示写入文件。)图像尺寸正确,颜色空间(在 JPEG 文件输出中)是 RGB,颜色profile 是 sRGB 等,这意味着我们没有处理损坏的图像(从某种意义上说,图像/位图数据本身是有效的)。我已经在 6.0 模拟器、7.0 模拟器和 7.0.6 设备上测试过这个案例,都一样。该层没有任何子层,我尝试将masksToBounds 设置为NO,但没有任何改变。

什么可能导致视图层不绘制?

【问题讨论】:

  • 您认为什么样的内容/层?有孩子吗?
  • 它是UIView 的常规CALayer。不,它没有任何子层。

标签: ios cocoa-touch cgimage cgimageref uigraphicscontext


【解决方案1】:

你需要改变:

[myView.layer drawInContext:UIGraphicsGetCurrentContext()];

到:

[myView.layer renderInContext:UIGraphicsGetCurrentContext()];

请注意,drawInContext: 默认情况下实际上并没有做任何事情:

该方法的默认实现不做任何绘图 本身。如果图层的委托实现了drawLayer:inContext: 方法,调用该方法进行实际绘图。

子类可以覆盖这个方法并用它来绘制图层的 内容。绘制时,所有坐标都应以点为单位指定 在逻辑坐标空间中。

UIView 的层委托被设置为 UIView,但它看起来并不像 UIView 必须绘制到提供的上下文。需要对此进行更多调查。

【讨论】:

  • 我已将其更改为renderInContext:,但仍然呈现黑色。
  • 这让我觉得你有一个不被尊重的 Alpha 通道。尝试将 opaque 参数设置为 NO。根据我建议的更改,我能够使用您的代码写出一个 PNG 文件。
  • 当我将opaque 设置为NO 时,我得到了一个完全透明的图像,而当我将它放入UIImageView 时,它根本不可见。
  • 您确定要在带有内容的 UIView 上调用它吗?尝试渲染[[[UIApplication sharedApplication] keyWindow] layer]
  • 是的,所以听起来 UIScrollView 发生了一些奇怪的事情,尽管我不知道是什么。我必须设计一个项目来解决这个问题。您还可以尝试对 UIScrollView 的父级进行快照。即使 UIScrollView 正在做一些神奇的渲染,我也希望它能够捕获图像。
【解决方案2】:

更新:根据 Rob Jones 的评论,不是这些 API 返回 UIView,而不是图像。

iOS 7 中有一个看起来很有前景的新 API:

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates NS_AVAILABLE_IOS(7_0);
- (UIView *)resizableSnapshotViewFromRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates withCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(7_0);  // Resizable snapshots will default to stretching the center
- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates NS_AVAILABLE_IOS(7_0);

检查UIView.h中的UIView (UISnapshotting)类别

【讨论】:

  • 它们看起来不错,但我也想支持 iOS 6,所以即使我有条件地在 iOS 7 上使用此 API,我仍然需要在 iOS 6 上使用备用方案。
  • 这前景如何?这个 API 只是返回另一个 UIView,它并没有真正推进将当前视图的内容存储到 UIImage 的目标。我是认真的。如果这样更容易,我真的很想知道如何。
  • 实际上它解决了我的问题,因为我需要另一个视图来显示(我正在尝试使用 UIImageView 来显示图像),但是如果我真的需要图像,是的,这个 API 不起作用。
  • @RobJones 你是对的——如果 OP 想要一张图片,这将无济于事。我读得不够仔细。
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 2011-02-24
  • 2017-05-12
  • 2012-12-18
  • 2014-04-23
  • 2018-09-06
相关资源
最近更新 更多