Ios 加速视图的碎片化
我有以下代码(在Ios 加速视图的碎片化,ios,swift,uiview,split,snapshot-view,Ios,Swift,Uiview,Split,Snapshot View,我有以下代码(在UIView的扩展中),它将UIView分割成一定数量的片段: public func fragment(into numberOfFragments: Int) -> [UIView] { var fragments = [UIView]() guard let containerView = superview, let snapshot = snapshotView(afterScreenUpdates: true) els
UIView
的扩展中),它将UIView
分割成一定数量的片段:
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秒钟才能完成。有没有办法更快地达到同样的效果我应该使用动画/过渡吗?
非常感谢。此解决方案使用UIImageView而不是UIView。它裁剪一个捕获的屏幕截图,而不是调用更昂贵的
resizeblesnapshotview
400次。如果AfterScreenUpdate
设置为false(适用于我的测试用例),则时间从~2.0秒下降到0.088秒。如果您需要AfterCreenUpdate
,则时间约为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
}
如果你看到的是一个相当可观的数额(20显然就是这个数额)来“分解一个图像”,你不应该只使用
UIKit
和UIView
。您正在达到使用CPU的门槛。这将需要一次重构,但至少需要CoreGraphics,甚至更多。(这取决于更多细节。)@dfd感谢您的建议。为了证实这一点,你是建议我考虑使用CoreGraphics,还是说这是一个CPU限制?感谢这个解决方案,效果很好。但是,containerView.drawHierarchy
应该是drawHierarchy
(在其他一些地方也是如此),因为我想分割的实际上是UIView
本身(而不是superview
)。无论如何谢谢你的帮助!干杯,很高兴它对你有用。对不起,我想我一定是有点糊涂了!;)顺便说一句:有点奇怪,但这是用于某种屏幕爆炸动画吗?是的,正是如此-所以传递一个你想删除的UICollectionViewCell
,比如说(let fragments cell.fragment…
)然后在对片段
sx
和y
位置进行某种动画处理后,从超级视图
中删除片段。:-)