请告诉我“放大/缩小”UICollectionView
并更改UICollectionViewCell
大小的最佳方法。我现在正在使用UIPinchGestureRecognizer
:当UICollectionView
“放大”和“缩小”时,会出现严重的延迟和冻结。
当我执行PinchGestureRecognizer时,如何摆脱带状装饰?
以下是UICollectionViewController中UIPinchGestureRecognizer的实现代码:
class BlocksCollectionViewController: UICollectionViewController, UIGestureRecognizerDelegate {
private var senderStartSize = CGFloat()
private var senderNormalPosition = CGSize()
override func viewDidLoad() {
super.viewDidLoad()
let pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:)))
pinchRecognizer.delegate = self
collectionView?.addGestureRecognizer(pinchRecognizer)
}
@objc func handlePinch(_ sender: UIPinchGestureRecognizer) {
guard let collection = collectionView else { return }
guard let layout = collection.collectionViewLayout as? CustomCollectionViewLayout else { return }
switch sender.state {
case .began:
senderStartSize = layout.cellSize
case .changed:
layout.cellSize = senderStartSize * sender.scale
layout.invalidateLayout()
default:
break
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
下面的代码是сustomCollectionViewLayout:
class CustomCollectionViewLayout: UICollectionViewLayout {
private var cellAttributes: [IndexPath: UICollectionViewLayoutAttributes] = [:]
var cellSize: CGFloat = 7
private var contentSize = CGSize.zero
override var collectionViewContentSize: CGSize {
return self.contentSize
}
override func prepare() {
guard let collection = collectionView else { return }
for section in 0...collection.numberOfSections - 2 {
for item in 0...collection.numberOfItems(inSection: section) - 2 {
let cellIndex = IndexPath(item: item, section: section)
let xPos = CGFloat(item) * cellSize
let yPos = CGFloat(section) * cellSize
let attributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex)
attributes.frame = CGRect(x: xPos, y: yPos, width: cellSize, height: cellSize)
cellAttributes[cellIndex] = attributes
}
}
let contentWidth = CGFloat(collection.numberOfItems(inSection: 0)) * cellSize
let contentHeight = CGFloat(collection.numberOfSections) * cellSize
contentSize = CGSize(width: contentWidth, height: contentHeight)
let centerOffsetX = (collection.contentSize.width - collection.frame.size.width) / 2
let centerOffsetY = (collection.contentSize.height - collection.frame.size.height) / 2
let centerPoint = CGPoint(x: centerOffsetX, y: centerOffsetY)
collection.setContentOffset(centerPoint, animated: false)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributesInRect = [UICollectionViewLayoutAttributes]()
for cellAttributes in cellAttributes.values {
if rect.intersects(cellAttributes.frame) {
attributesInRect.append(cellAttributes)
}
}
return attributesInRect
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cellAttributes[indexPath]
}
}
答案 0 :(得分:0)
很抱歉这样说,但我的猜测是问题不在你的代码中,而在于它的工作方式。因为我看到你有大量的细胞使它难以处理,这就是它开始滞后的原因。
您是否尝试过使用真实设备?比较最新的iPhone和旧的iPhone?我确定你会看到渲染速度的差异。
但无论如何,随着更多的计算/表达,你会有更多的表现。而且,循环很昂贵。
顺便说一句,作为一种解决方案(如果应用程序的业务方面接受它),您可以不放大/缩小,而是放大/缩小2个按钮。我认为它不会导致滞后,但它确实不那么酷。
答案 1 :(得分:0)
在这种情况下,我建议您使用Xcode Time Profiler来调试性能。您将找到导致延迟的部分并在以后进行优化。祝你好运:)
答案 2 :(得分:0)
由于我的收藏中有很多UICollectionViewCells,最好的方法是:
1)将UICollectionView放在containerView(简单的UIView)上,并将此容器放在UIScrollView上。
我限制缩放:
scrollView.minimumZoomScale = 1
scrollView.maximumZoomScale = 6
2)并使用了UIScrollViewDelegate的函数:
func scrollViewDidZoom(_ scrollView: UIScrollView) {
// Code for processing zoom - scrollView.zoomScale,
// contentOffset, contentSize etc....
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return containerView
}