如何从UIView生成包含经过变换的UIImageView的PDF文件?
解决UIView生成PDF时UIImageView变换不生效的问题
我明白你遇到的痛点了——当你遍历带自视图的UIView并在PDF上下文重绘时,UIImageView的变换(比如旋转、缩放、平移)完全没生效,对吧?这是因为你直接绘制UIImage的话,根本没把UIImageView本身的视图变换考虑进去,这些变换是属于UIView层级的渲染状态,不是图片数据自带的属性。
下面给你梳理修正思路和可直接用的代码:
核心解决思路
要正确呈现带变换的UIImageView,要么在PDF上下文里先应用UIImageView的transform,再绘制图片;要么直接把整个UIImageView的完整渲染结果(包括变换)输出到PDF上下文,不用单独处理image属性。
方案一:单独处理UIImageView的变换
如果你需要针对UIImageView做特殊逻辑,用这个实现:
NSMutableData *pdfData = [NSMutableData data]; CGRect pageFrame = CGRectMake(0, 0, aView.frame.size.width, aView.frame.size.height); UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil); UIGraphicsBeginPDFPageWithInfo(pageFrame, nil); // 获取当前PDF绘图上下文 CGContextRef pdfContext = UIGraphicsGetCurrentContext(); // 遍历目标视图的所有子视图 for (UIView *subview in aView.subviews) { if ([subview isKindOfClass:[UIImageView class]]) { UIImageView *imgv = (UIImageView *)subview; // 保存当前上下文状态,避免变换影响其他视图绘制 CGContextSaveGState(pdfContext); // 调整坐标系+应用视图变换:Core Graphics坐标系和UIKit翻转,需要先对齐 CGContextTranslateCTM(pdfContext, imgv.center.x, imgv.center.y); CGContextConcatCTM(pdfContext, imgv.transform); CGContextTranslateCTM(pdfContext, -imgv.bounds.size.width/2, -imgv.bounds.size.height/2); // 绘制带变换的图片 [imgv.image drawInRect:imgv.bounds]; // 恢复上下文初始状态 CGContextRestoreGState(pdfContext); } else { // 其他类型视图直接渲染图层(自带所有样式和变换) [subview.layer renderInContext:pdfContext]; } } UIGraphicsEndPDFContext();
方案二:更简洁的全视图渲染(推荐)
如果你不需要单独处理UIImageView,直接渲染整个视图的图层就可以自动包含所有子视图的变换、阴影、圆角等效果,代码更省心:
NSMutableData *pdfData = [NSMutableData data]; CGRect pageFrame = CGRectMake(0, 0, aView.frame.size.width, aView.frame.size.height); UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil); UIGraphicsBeginPDFPageWithInfo(pageFrame, nil); CGContextRef pdfContext = UIGraphicsGetCurrentContext(); // 翻转坐标系,匹配UIKit的左上角原点规则 CGContextTranslateCTM(pdfContext, 0, pageFrame.size.height); CGContextScaleCTM(pdfContext, 1.0, -1.0); // 直接渲染整个视图树(包含所有子视图的变换和样式) [aView.layer renderInContext:pdfContext]; UIGraphicsEndPDFContext();
为什么原代码会失效?
你之前的代码只提取了UIImageView的image属性来绘制,但UIImage本身不存储任何视图层面的变换信息——旋转、缩放这些效果是UIImageView的layer在渲染时实时计算的,属于视图的渲染状态,不是图片数据的一部分,所以直接画自然看不到变换效果。
内容的提问来源于stack exchange,提问作者Hiren Prajapati
相关产品推荐
相关产品推荐

