如何解决集合视图:在转换时重绘单元格
我有一个基于框架大小绘制单元格的集合视图。当视图旋转时,单元格当前没有被重绘并保持完全相同的配置,忽略新的帧大小并溢出。调用打印语句“强制重新加载”。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("Force Reload")
let layout = collectionView.collectionViewLayout as? CustomCollectionViewLayout
layout?.invalidateLayout()
}
集合视图属于以下自定义布局类。
自定义布局类:
import UIKit
protocol CustomCollectionViewDelegate: class {
func theNumberOfItemsInCollectionView() -> Int
}
extension CustomCollectionViewDelegate {
func heightForContentInItem(inCollectionView collectionView: UICollectionView,at indexPath: IndexPath) -> CGFloat {
return 0
}
}
class CustomCollectionViewLayout: UICollectionViewLayout {
fileprivate var numberOfColumns = 3
fileprivate var cellPadding: CGFloat = 0
fileprivate var cellHeight: CGFloat = 110
weak var delegate: CustomCollectionViewDelegate?
//An array to cache the calculated attributes
fileprivate var cache = [UICollectionViewLayoutAttributes]()
//For content size
fileprivate var contentHeight: CGFloat = 0
fileprivate var contentWidth: CGFloat {
guard let collectionView = collectionView else {return 0}
let insets = collectionView.contentInset
return collectionView.bounds.width - (insets.left + insets.right)
}
//Setting the content size
override var collectionViewContentSize: CGSize {
return CGSize(width: contentWidth,height: contentHeight)
}
override func prepare() {
//Measure the location of items only if the cache is empty
guard cache.isEmpty == true,let collectionView = collectionView else {return}
if UIDevice.current.userInterfaceIdiom == .pad {
cellHeight = 190
}
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset = [CGFloat]()
//Getting the xOffset based on the column and column width
for column in 0..<numberOfColumns {
if column == 0 {
xOffset.append(0)
}
if column == 1 {
xOffset.append(2 * columnWidth)
}
if column == 2
{
xOffset.append( columnWidth)
}
// xOffset.append(CGFloat(column) * columnWidth)
}
var column = 0
var yOffset = [CGFloat]()
for item in 0..<collectionView.numberOfItems(inSection: 0) {
let indexPath = IndexPath(item: item,section: 0)
//Different offset based on what column the item is
for column in 0..<numberOfColumns {
switch column {
case 0:
yOffset.append(2 * cellPadding)
case 1:
yOffset.append(2 * cellPadding)
case 2:
yOffset.append(cellPadding + cellHeight)
default:
break
}
}
//Measuring the frame
let height = cellPadding * 2 + cellHeight
let frame = CGRect(x: xOffset[column],y: yOffset[column],width: columnWidth,height: columnWidth)
let insetFrame = frame.insetBy(dx: cellPadding,dy: cellPadding)
//Creating attributes for the layout and caching them
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)
print ("frame.maxY",frame.maxY)
//We increase the max height of the content as we get more items
contentHeight = max(collectionView.frame.height + 10,frame.maxY)
//We increase the yOffset,too
yOffset[column] = yOffset[column] + 2 * (height - cellPadding)
// print ("column: \(column),yOffset: \(yOffset[column])")
let numberOfItems = delegate?.theNumberOfItemsInCollectionView()
//Changing column so the next item will be added to a different column
if let numberOfItems = numberOfItems,indexPath.item == numberOfItems - 1
{
//In case we get to the last cell,we check the column of the cell before
//The last one,and based on that,we change the column
print ("indexPath.item: \(indexPath.item),numberOfItems: \(numberOfItems)")
print ("A")
switch column {
case 0:
column = 2
case 2:
column = 0
case 1:
column = 2
default:
return
}
} else {
print ("B")
column = column < (numberOfColumns - 1) ? (column + 1) : 0
}
}
// }
}
//Is called to determine which items are visible in the given rect
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]()
//Loop through the cache and look for items in the rect
for attribute in cache {
if attribute.frame.intersects(rect) {
visibleLayoutAttributes.append(attribute)
}
}
return visibleLayoutAttributes
}
//The attributes for the item at the indexPath
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cache[indexPath.item]
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。