ios - 加速视图的碎片化
问题描述
我有以下代码(在 的扩展内UIView
)将 aUIView
分成一定数量的片段:
public func fragment(into numberOfFragments: Int) -> [UIView] {
var fragments = [UIView]()
guard let containerView = superview, let snapshot = snapshotView(afterScreenUpdates: true) else { return fragments }
let fragmentWidth = snapshot.frame.width / CGFloat(numberOfFragments)
let fragmentHeight = snapshot.frame.height / CGFloat(numberOfFragments)
for x in stride(from: 0.0, to: snapshot.frame.width, by: fragmentWidth) {
for y in stride(from: 0.0, to: snapshot.frame.height, by: fragmentHeight) {
let rect = CGRect(x: x, y: y, width: fragmentWidth, height: fragmentHeight)
if let fragment = snapshot.resizableSnapshotView(from: rect, afterScreenUpdates: true, withCapInsets: .zero) {
fragment.frame = convert(rect, to: containerView)
containerView.addSubview(fragment)
fragments.append(fragment)
}
}
}
return fragments
}
但是,numberOfFragments=20
此代码大约需要 2 秒才能完成。有没有办法以更快的方式实现同样的结果?我应该改用动画/过渡吗?
非常感谢。
解决方案
此解决方案使用 UIImageViews 而不是 UIViews。它裁剪单个捕获的屏幕截图,而不是调用更昂贵的resizableSnapshotView
400 次。afterScreenUpdates
如果设置为 false(适用于我的测试用例),时间从 ~2.0 秒下降到 0.088 秒。如果afterScreenUpdates
您的目的需要,则时间约为 0.15 秒。仍然 - 比 2.0 秒快得多!
public func fragment(into numberOfFragments: Int) -> [UIImageView] {
var fragments = [UIImageView]()
guard let containerView = superview else { return fragments }
let renderer = UIGraphicsImageRenderer(size: containerView.bounds.size)
let image = renderer.image { ctx in
containerView.drawHierarchy(in: containerView.bounds, afterScreenUpdates: false)
}
let fragmentWidth = containerView.frame.width / CGFloat(numberOfFragments)
let fragmentHeight = containerView.frame.height / CGFloat(numberOfFragments)
for x in stride(from: 0.0, to: containerView.frame.width, by: fragmentWidth) {
for y in stride(from: 0.0, to: containerView.frame.height, by: fragmentHeight) {
let rect = CGRect(x: x, y: y, width: fragmentWidth, height: fragmentHeight)
if let imageFrag = cropImage(image, toRect: rect) {
let fragment = UIImageView(image: imageFrag)
fragment.frame = convert(rect, to: containerView)
containerView.addSubview(fragment)
fragments.append(fragment)
}
}
}
return fragments
}
func cropImage(_ inputImage: UIImage, toRect cropRect: CGRect) -> UIImage?
{
let imageViewScale = UIScreen.main.scale
// Scale cropRect to handle images larger than shown-on-screen size
let cropZone = CGRect(x:cropRect.origin.x * imageViewScale,
y:cropRect.origin.y * imageViewScale,
width:cropRect.size.width * imageViewScale,
height:cropRect.size.height * imageViewScale)
// Perform cropping in Core Graphics
guard let cutImageRef: CGImage = inputImage.cgImage?.cropping(to:cropZone)
else {
return nil
}
// Return image to UIImage
let croppedImage: UIImage = UIImage(cgImage: cutImageRef)
return croppedImage
}
推荐阅读
- mysql - 自加入 - 当我尝试进行自加入时,我的查询显示匹配和不匹配的值
- python - 带有 Tensorflow 的神经网络不会更新权重/偏差
- django - 使用 python+django+gunicorn + worker 无法启动 Gcloud 应用程序部署失败
- html - 如何自动生成唯一的 CSS 选择器
- jquery - 显示每个中继器项目的值
- python - 从python中的迭代对象创建一个带有一组树的迭代对象
- mysql - 每个组的 MySQL top-N 排名,基于最新组的行
- html - 将多种背景颜色设置为 H1
- google-sheets - 用于日期检测的 Google 表格公式
- r - 如何在素食包的布雷 nmds 分析中添加椭圆