1.将整个view截图返回image:
这些 api 已被废弃,所以需要判断 iOS 版本 写两套代码:
Replace usage of UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer.
Replace usage of UIGraphicsGetImageFromCurrentImageContext with UIGraphicsImageRendererContext.currentImage.
Swift 版本:
- /// 截图整个view
- /// - Returns: image
- func mooSnapshot() -> UIImage? {
- if self.window == nil {
- return nil
- }
- let scale = UIScreen.main.scale
- var image: UIImage? = nil
- // 1. 创建绘图渲染格式
- if #available(iOS 10.0, *) {
- let format = UIGraphicsImageRendererFormat()
- format.scale = scale
- format.opaque = false
- // 2. 创建绘图渲染器
- let renderer = UIGraphicsImageRenderer(size: self.bounds.size,
- format: format)
- // 3. 绘制图
- image = renderer.image { context in
- let success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
- print("draw success: \(success)")
- }
- } else {
- UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, scale);
- let success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
- print("draw success: \(success)")
- image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- }
- return image
- }
复制代码 OC版本:
- - (UIImage * _Nullable)mooSnapshot {
- if (CGRectGetWidth(self.bounds) <= 0.0 || CGRectGetHeight(self.bounds) <= 0.0) {
- return nil;
- }
- if (!self.window) {
- return nil;
- }
- if (!self.superview) {
- return nil;
- }
- CGFloat scale = [UIScreen mainScreen].scale;
- UIImage *image = nil;
- if (@available(iOS 10.0, *)) {
- UIGraphicsImageRendererFormat *format = [[UIGraphicsImageRendererFormat alloc] init];
- format.scale = scale;
- format.opaque = NO;
- UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:self.bounds.size
- format:format];
- image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
- BOOL success = [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
- NSLog(@"%p, Snapshot success: %@", self, @(success));
- }];
- } else {
- UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, scale);
- BOOL success = [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
- NSLog(@"%p, Snapshot success: %@", self, @(success));
- image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- }
- return image;
- }
复制代码 2.截取view的部门区域,返回image:
Capture the frame area of the view.
Swift 版本:
- import CoreGraphics
- extension UIView {
- /// 截取view的部分区域
- /// - Parameter frame: 需要截取的区域
- /// - Returns: image
- func mooSnapshotForFrame(_ frame: CGRect) -> UIImage? {
- guard let image = self.mooSnapshot() else { return nil }
- guard let cgImage = image.cgImage else { return nil }
- let scale = UIScreen.main.scale
- // 根据屏幕倍率将 frame 进行缩放
- let scaledRect = CGRectApplyAffineTransform(frame,
- CGAffineTransformMakeScale(scale, scale))
- // 根据 缩放frame 进行裁剪
- guard let scaledCGImage = cgImage.cropping(to: scaledRect) else { return nil }
- let returnImage = UIImage(cgImage: scaledCGImage)
- return returnImage
- }
- }
复制代码 OC 版本:
- - (UIImage * _Nullable)mooSnapshotForFrame:(CGRect)frame {
- if (CGRectGetWidth(frame) <= 0.0 || CGRectGetHeight(frame) <= 0.0) {
- return nil;
- }
- UIImage *image = [self mooSnapshot];
- if (!image) {
- return nil;
- }
- CGFloat scale = [UIScreen mainScreen].scale;
- CGRect scaledRect = CGRectApplyAffineTransform(frame, CGAffineTransformMakeScale(scale, scale));
- CGImageRef cgImage = CGImageCreateWithImageInRect(image.CGImage, scaledRect);
- UIImage *returnImage = [UIImage imageWithCGImage:cgImage];
- CGImageRelease(cgImage);
- return returnImage;
- }
复制代码 以下就是将一个view的上半部门截取成image后展示如下:
3.旧方法:
- func mooSnapshot() -> UIImage? {
- guard CGRectGetWidth(self.bounds) > 0.0 && CGRectGetHeight(self.bounds) > 0.0 else {
- return nil
- }
- UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
- let success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
- print("draw success: \(success)")
- let image = UIGraphicsGetImageFromCurrentImageContext()
- UIGraphicsEndPDFContext()
- return image
- }
复制代码 Replace usage of UIGraphicsBeginImageContext with UIGraphicsImageRenderer.
Replace usage of UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer.
Replace usage of UIGraphicsGetImageFromCurrentImageContext with UIGraphicsImageRendererContext.currentImage.
UIGraphicsEndImageContext should only be used alongside UIGraphicsBeginImageContext[WithOptions].
这些旧的 api 已经被废弃了,用文章开头的 api 取代
4.Tips
Tips1:得在加载到父视图 layout 后触发
Tips2:width 或 height 有一个为空 drawHierarchy 就会 crash(就版iOS不会crash,新版会)
参考:
drawViewHierarchyInRect:afterScreenUpdates:
ios drawViewHierarchyInRect crash EXC_BREAKPOINT UNKNOWN
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |