swift – UICollectionView自动调整大小和动态行数
发布时间:2020-12-14 04:44:46 所属栏目:百科 来源:网络整理
导读:我想做这样的事情: 基本上,我使用的是UICollectionView和单元格(3个不同的.xib). 到目前为止,它的确有效. 我想做的是: 设置自动高度 如果旋转,请向UIColectionView添加1行 2.1如果平板电脑,在肖像上将有2行和横向3行. (基本上与第2点相同,只增加1行. 我有
我想做这样的事情:
基本上,我使用的是UICollectionView和单元格(3个不同的.xib). 到目前为止,它的确有效. 我想做的是: >设置自动高度 我有这样的事情: extension ViewController { override func viewWillTransition(to size: CGSize,with coordinator: UIViewControllerTransitionCoordinator){ setSizeSize() } func setSizeSize(){ if(DeviceType.IS_IPAD || UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight){ if let layout = myCollectionView.collectionViewLayout as? UICollectionViewFlowLayout { layout.estimatedItemSize = CGSize(width: 1,height: 1) layout.invalidateLayout() } }else{ if let layout = myCollectionView.collectionViewLayout as? UICollectionViewFlowLayout { layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize layout.invalidateLayout() } } myCollectionView.collectionViewLayout.invalidateLayout() } } 不行.此外,它冻结设备.在模拟器上工作特殊. (我相信更多的设备) 我也尝试了this,但有时它有效… 如果您需要更多信息,请告诉我. 提前谢谢大家的帮助. 解决方法
我建议你创建自己的UICollectionViewFlowLayout子类,它将生成所需的布局.这是一个可以使用的简单流程布局.如果我错过了什么,你可以根据自己的需要调整它.
public protocol CollectionViewFlowLayoutDelegate: class { func numberOfColumns() -> Int func height(at indexPath: IndexPath) -> CGFloat } public class CollectionViewFlowLayout: UICollectionViewFlowLayout { private var cache: [IndexPath : UICollectionViewLayoutAttributes] = [:] private var contentHeight: CGFloat = 0 private var contentWidth: CGFloat { guard let collectionView = collectionView else { return 0 } let insets = collectionView.contentInset return collectionView.bounds.width - (insets.left + insets.right) } public weak var flowDelegate: CollectionViewFlowLayoutDelegate? public override var collectionViewContentSize: CGSize { return CGSize(width: self.contentWidth,height: self.contentHeight) } public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var layoutAttributesArray = [UICollectionViewLayoutAttributes]() if cache.isEmpty { self.prepare() } for (_,layoutAttributes) in self.cache { if rect.intersects(layoutAttributes.frame) { layoutAttributesArray.append(layoutAttributes) } } return layoutAttributesArray } public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return self.cache[indexPath] } public override func prepare() { guard let collectionView = self.collectionView else { return } let numberOfColumns = self.flowDelegate?.numberOfColumns() ?? 1 let cellPadding: CGFloat = 8 self.contentHeight = 0 let columnWidth = UIScreen.main.bounds.width / CGFloat(numberOfColumns) var xOffset = [CGFloat]() for column in 0 ..< numberOfColumns { xOffset.append(CGFloat(column) * columnWidth) } var column = 0 var yOffset = [CGFloat](repeating: 0,count: numberOfColumns) for item in 0 ..< collectionView.numberOfItems(inSection: 0) { let indexPath = IndexPath(item: item,section: 0) let photoHeight = self.flowDelegate?.height(at: indexPath) ?? 1 let height = cellPadding * 2 + photoHeight let frame = CGRect(x: xOffset[column],y: yOffset[column],width: columnWidth,height: height) let insetFrame = frame.insetBy(dx: cellPadding,dy: cellPadding) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) attributes.frame = insetFrame self.cache[indexPath] = attributes self.contentHeight = max(self.contentHeight,frame.maxY) yOffset[column] = yOffset[column] + height column = column < (numberOfColumns - 1) ? (column + 1) : 0 } } } 现在在你的UIViewController中你可以像这样使用它: override func viewDidLoad() { super.viewDidLoad() let flowLayout = CollectionViewFlowLayout() flowLayout.flowDelegate = self self.collectionView.collectionViewLayout = flowLayout } 在更改方向后,使collectionView布局无效 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() guard let flowLayout = self.collectionView.collectionViewLayout as? CollectionViewFlowLayout else { return } flowLayout.invalidateLayout() } 现在使ViewController符合CollectionViewFlowLayoutDelegate extension ViewController: CollectionViewFlowLayoutDelegate { func height(at indexPath: IndexPath) -> CGFloat { guard let cell = self.collectionView.cellForItem(at: indexPath) else { return 1 } cell.layoutIfNeeded() //get calculated cell height return cell.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height } func numberOfColumns() -> Int { //how much columns would be shown,depends on orientation return UIDevice.current.orientation == .portrait ? 2 : 3 } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |