将UIImageVIew
(imageView
)添加到self.view
,将相册视图完美地捕获:
CGSize size = CGSizeMake(self.view.frame.size.height, self.view.frame.size.width);
UIGraphicsBeginImageContext(size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);
但是,如果imageView
子视图按以下方式旋转:
[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
再次捕获self.view
并不反映轮换。子视图imageView
好像没有旋转。
如何使renderInContext
适用于按CABasicAnimation
旋转的子视图?
更新:
警告:CALayer / -renderInContext:方法未实现 完整的核心动画组合模型。下面提供的代码将是 能够解决大多数情况,但有一些事情 CALayer / -renderInContext:方法无法正确呈现,因此您可以 希望联系开发人员技术支持以获取变通方法请求。
官方Apple Technical Q& A QA1703建议联系开发者技术支持部门以获取变通方法请求。
是否已存在解决方法?
答案 0 :(得分:5)
layer.presentationLayer
时使用layer
代替renderInContext
。
这是一个类别,用于截取 UIView ,UIView + Screenshot.h的屏幕截图:
//
// UIView+Screenshot.h
//
// Created by Horace Ho on 2012/12/11.
// Copyright (c) 2012 Horace Ho. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
@interface UIView (HHScreenShot)
- (UIImage *)screenshot:(UIDeviceOrientation)orientation isOpaque:(BOOL)isOpaque usePresentationLayer:(BOOL)usePresentationLayer;
@end
@implementation UIView (HHScreenShot)
- (UIImage *)screenshot:(UIDeviceOrientation)orientation isOpaque:(BOOL)isOpaque usePresentationLayer:(BOOL)usePresentationLayer
{
CGSize size;
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
size = CGSizeMake(self.frame.size.width, self.frame.size.height);
} else {
size = CGSizeMake(self.frame.size.height, self.frame.size.width);
}
UIGraphicsBeginImageContextWithOptions(size, isOpaque, 0.0);
if (usePresentationLayer) {
[self.layer.presentationLayer renderInContext:UIGraphicsGetCurrentContext()];
} else {
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@end
使用:
UIImage *image = [self.view screenshot:UIDeviceOrientationPortrait
isOpaque:YES
usePresentationLayer:YES];
答案 1 :(得分:1)
来自文档:
此方法直接从图层树渲染,忽略添加到渲染树的任何动画。
您必须从表示层读取旋转并旋转图形上下文。
答案 2 :(得分:1)
您应该能够将renderInContext与表示层一起使用。虽然这可能不适合您的层次结构。因此,如果您执行以下任一操作,这可能是最简单的:
答案 3 :(得分:0)
正如大卫所说,动画不是由renderInContext呈现的。动画应用于表示层,仅显示。
最简单的方法是将旋转应用于禁止隐式动画的CATransaction中的图层,然后捕获图层。
我相信这会奏效。 (但我没有尝试过那个特定的东西,所以我不是肯定的。)
或者,您可以设置动画,以便在动画完成后不会将它们设置为保持有效,而是在动画开始之前更改基础属性。然后,当您渲染图层时,子图层应绘制其最终位置。
渲染“飞行中”动画会更加棘手。为此,您需要遍历图层树,查询每个图层的表示层,并将您正在设置动画的设置传输到基础层。但是,一旦动画完成,这会搞砸你的图层,所以你需要以某种方式保存每个属性的值,从表示层设置它的“飞行中”值,捕获你的图像,然后设置属性/返回每个图层的属性,所有属性都在禁用动画的CATransaction中。