截取含UIVisualEffectView的视图后无法裁剪指定区域,求解决方案
解决UIVisualEffectView截图并裁剪指定区域的问题
我完全懂你遇到的困扰——UIVisualEffectView的模糊效果确实依赖于它所在的窗口上下文,单独渲染它的layer根本留不住模糊效果,你想先截整个父视图再裁剪的思路是对的,但问题出在坐标转换和截图细节处理上。
先给你直接上修改后的可运行代码,再拆解关键问题:
@IBAction func btnTapped(_ sender: Any) { // 获取屏幕缩放比例,保证截图清晰度 let scale = UIScreen.main.scale let parentViewSize = view.bounds.size // 创建适配屏幕scale的截图上下文 UIGraphicsBeginImageContextWithOptions(parentViewSize, false, scale) defer { UIGraphicsEndImageContext() } // 确保上下文一定会被释放,避免内存泄漏 // 渲染整个父视图,这里直接传view的bounds即可(drawHierarchy的in参数是视图自身的坐标系) view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) guard let fullScreenshot = UIGraphicsGetImageFromCurrentImageContext(), let fullCGImage = fullScreenshot.cgImage else { return } // 把目标视图的frame转换为截图像素级的坐标(因为CGImage是基于像素的,需要乘以scale) let targetViewFrame = viewScreenShot.frame let scaledCropRect = CGRect( x: targetViewFrame.origin.x * scale, y: targetViewFrame.origin.y * scale, width: targetViewFrame.size.width * scale, height: targetViewFrame.size.height * scale ) // 裁剪出目标区域的CGImage guard let croppedCGImage = fullCGImage.cropping(to: scaledCropRect) else { return } // 用原scale创建UIImage,保证显示比例正确 let finalImage = UIImage(cgImage: croppedCGImage, scale: scale, orientation: .up) // 赋值给对应的UIImageView (view.viewWithTag(90) as? UIImageView)?.image = finalImage }
关键修改点说明
修复drawHierarchy的参数错误
你之前传的view.frame.origin是视图相对于父容器的坐标,但drawHierarchy的in参数要求传入视图自身坐标系下的区域,直接传view.bounds就能完整渲染整个父视图。处理屏幕缩放比例(scale)
因为截图上下文用了屏幕原生scale(传0会自动适配),生成的UIImage的CGImage是像素级的,所以裁剪时必须把目标视图的frame坐标和尺寸都乘以scale,才能对应到正确的像素区域,否则裁剪出来的内容会偏移或尺寸不对。安全的上下文管理
用defer语句确保截图上下文一定会被释放,避免潜在的内存泄漏问题。可选值安全处理
给关键步骤加了guard let判断,避免因为可选值为空导致崩溃。
如果viewScreenShot是嵌套在多层子视图里的,你还需要先把它的坐标转换到父视图(self.view)的坐标系下,用这个方法即可:
let convertedFrame = viewScreenShot.convert(viewScreenShot.bounds, to: view)
内容的提问来源于stack exchange,提问作者Prashant Tukadiya
相关产品推荐
相关产品推荐

