swift - 将 UIView 保存为图像会导致其子视图的 zPositioning 失败
问题描述
我需要将我的应用中的视图保存为 .png 图像。该视图包含 4 个子视图,每个子视图通过 zPosition - subview.layer.zPosition 在不同的层上。
主视图 -
- 子视图 1 (UITextView) - zPosition = 0
- 子视图 2 (UITextView) - zPosition = 1
- 子视图 3 (UITextView) - zPosition = 2
- 子视图 4 (UITextView) - zPosition = 3
我对 UIView 有以下扩展功能。图像保存但忽略了子视图的 zPositioning。Suvbview 在生成的保存图像中以错误的顺序堆叠在一起。我的代码如下:
extension UIView {
func asImage() -> UIImage {
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
layer.render(in: rendererContext.cgContext)
}
}
}
}
我这样称呼它:
var snapshot: UIImage? = mainView.asImage()
经过一些谷歌搜索后,我发现手动重新排序子视图然后在每个子视图上调用 rendererContext 可以解决这个问题。它适用于 zPositioning,所有元素现在都正确堆叠,但所有元素现在都失去了相对于 mainView 的 x/y 定位。我可以看到这是因为主视图现在被忽略了,但我正在努力解决这个问题。有人可以帮忙吗?
extension UIView {
func asImage() -> UIImage {
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
let orderedLayers = self.subviews.sorted(by: {
$0.layer.zPosition < $1.layer.zPosition
})
for l in orderedLayers {
l.layer.render(in: rendererContext.cgContext)
}
}
}
}
}
解决方案
我想通了这一点,所以万一其他人遇到这个问题,解决方案是将每个新排序的层添加回父视图(在这种情况下为父视图调用扩展函数时的自身)。修改后的代码如下:
func asImage() -> UIImage {
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
let orderedLayers = self.subviews.sorted(by: {
$0.layer.zPosition < $1.layer.zPosition
})
for l in orderedLayers {
self.addSubview(l)
}
layer.render(in: rendererContext.cgContext)
}
}
}
推荐阅读
- android - Android SyncAdapter 导致 InterruptedException
- alexa - ask-cli api 或 lambda 不存在
- fullcalendar - 使用Javascript从外部修改约会事件
- javascript - 使用base64在javascript中将图像转换为二进制
- ios - 如何在 iOS Swift 4 中更改已加载 NibView 的位置?
- android - 如何从android中的画廊上传多张图片?
- java - 无法使用 Java 客户端通过 Appium 滚动 Android 应用程序
- python - 如何绘制饼图?
- neo4j - 在 Neo4j 中使用 cypher 的双向连接图
- javascript - 添加不同文本字段的两个值以在多行上填充另一个文本字段