如何在单个列中设置每个UICollectionView部分

我有一个UICollectionView ,它包含给定数量的sections ,每个sections由给定数量的rows

现在,由于我将网格布局指定为垂直,因此UICollectionView看起来像这样:

在此处输入图像描述

但是当屏幕的宽度放大时,例如在横向模式或IPad上,我希望collectionView有一个水平网格,网格中的每一行我都会将它垂直包含每个UICollectionView sections

像这样的东西:

像这样的东西:

有一种简单的方法可以解决这个问题吗?

我在UICollectionViewController尝试过UICollectionViewController

单击CollectionView并更改为CustomLayout [UICollectionViewLayout]

在此处输入图像描述

UICollectionViewController

 let values = [["a","b","c","d","e","f"], ["a","b","c"], ["a","b","c","d"], ["a","b","c","d","e","f"], ["a","b","c","d","e","f"],["a","b","c","d","e","f"], ["a","b","c"], ["a","b","c","d"], ["a","b","c","d","e","f"], ["a","b","c","d","e","f"]] override func viewDidLoad() { super.viewDidLoad() let XIB = UINib.init(nibName: "RulesExrView", bundle: Bundle.main) rulesCollexnVw.register(XIB, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerreuse") } override func numberOfSections(in collectionView: UICollectionView) -> Int { // #warning Incomplete implementation, return the number of sections return values.count } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of items return values[section].count } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! RulesCollectionViewCell let text = values[indexPath.section][indexPath.item] cell.backgroundColor = UIColor.clear cell.layer.borderColor = UIColor(red: 81/255, green: 57/255, blue: 141/255, alpha: 1.0).cgColor cell.layer.borderWidth = 1.0 cell.txtLbl.text = text cell.txtLbl.textAlignment = .center cell.txtLbl.textColor = .white cell.layer.cornerRadius = 5 return cell } override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print("\n\n Selected indPath ", indexPath) } override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { print("Kinddd ", kind) switch kind { case UICollectionElementKindSectionHeader: if let supplementaryView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerreuse", for: indexPath) as? RulesReusableView { // Configure Supplementary View supplementaryView.backgroundColor = UIColor.clear supplementaryView.headLbl.text = "Section \(indexPath.section)".uppercased() supplementaryView.headLbl.textColor = UIColor.white return supplementaryView } fatalError("Unable to Dequeue Reusable Supplementary View") default: assert(false, "Unexpected element kind") } } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { if UIDevice.current.orientation.isLandscape { print("Landscape") rulesCollexnVw.reloadData() } else { print("Portrait") rulesCollexnVw.reloadData() } } 

UICollectionViewLayout [不是UICollectionViewFlowLayout]

 class RulesLayout: UICollectionViewLayout { let CELL_HEIGHT = 30.0 let CELL_WIDTH = 100.0 let horizontalSpacing = 5.0 let verticalSpaing = 5.0 let headerSpacing = 40.0 let STATUS_BAR = UIApplication.shared.statusBarFrame.height var portrait_Ypos : Double = 0.0 var cellAttrsDictionary = Dictionary() var contentSize = CGSize.zero var dataSourceDidUpdate = true override var collectionViewContentSize : CGSize { return self.contentSize } override func prepare() { dataSourceDidUpdate = false if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight { if let sectionCount = collectionView?.numberOfSections, sectionCount > 0 { for section in 0...sectionCount-1 { let xPos = (Double(section) * CELL_WIDTH) + (Double(section) * horizontalSpacing) var yPos : Double = 0.0 if let rowCount = collectionView?.numberOfItems(inSection: section), rowCount > 0 { for item in 0...rowCount-1 { let cellIndex = IndexPath(item: item, section: section) if item == 0 { portrait_Ypos = headerSpacing } else { portrait_Ypos = portrait_Ypos + CELL_HEIGHT + verticalSpaing } yPos = portrait_Ypos let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex) cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT) // Determine zIndex based on cell type. if section == 0 && item == 0 { cellAttributes.zIndex = 4 } else if section == 0 { cellAttributes.zIndex = 3 } else if item == 0 { cellAttributes.zIndex = 2 } else { cellAttributes.zIndex = 1 } cellAttrsDictionary[cellIndex] = cellAttributes } } } } let contentWidth = Double(collectionView!.numberOfSections) * CELL_WIDTH + (Double(collectionView!.numberOfSections - 1) * horizontalSpacing) let contentHeight = Double(collectionView!.numberOfSections) * CELL_HEIGHT self.contentSize = CGSize(width: contentWidth, height: contentHeight) print("self.contentSizeself.contentSize ", self.contentSize) } else { if let sectionCount = collectionView?.numberOfSections, sectionCount > 0 { for section in 0...sectionCount-1 { let xPos = (Double(UIScreen.main.bounds.width) - CELL_WIDTH) / 2.0 if let rowCount = collectionView?.numberOfItems(inSection: section), rowCount > 0 { for item in 0...rowCount-1 { let cellIndex = IndexPath(item: item, section: section) if section != 0 { if item == 0 { portrait_Ypos = portrait_Ypos + CELL_HEIGHT + headerSpacing } else { portrait_Ypos = portrait_Ypos + CELL_HEIGHT + verticalSpaing } } else { if item == 0 { portrait_Ypos = headerSpacing } else { portrait_Ypos = portrait_Ypos + CELL_HEIGHT + verticalSpaing } } let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex) cellAttributes.frame = CGRect(x: xPos, y: portrait_Ypos, width: CELL_WIDTH, height: CELL_HEIGHT) if section == 0 && item == 0 { cellAttributes.zIndex = 4 } else if section == 0 { cellAttributes.zIndex = 3 } else if item == 0 { cellAttributes.zIndex = 2 } else { cellAttributes.zIndex = 1 } cellAttrsDictionary[cellIndex] = cellAttributes } } } } let contentWidth = UIScreen.main.bounds.width let contentHeight = CGFloat(portrait_Ypos) + CGFloat(CELL_HEIGHT) self.contentSize = CGSize(width: contentWidth, height: contentHeight) print("sPort.contentSize ", self.contentSize) } } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var attributesInRect = [UICollectionViewLayoutAttributes]() for cellAttributes in cellAttrsDictionary.values { if rect.intersects(cellAttributes.frame) { attributesInRect.append(cellAttributes) let celIndPth = cellAttributes.indexPath if celIndPth.item == 0 { // YOU HAVE TO ADD SUPPLEMENTARY HEADER TO THIS LAYOUT ATTRIBUTES if let supplementaryAttributes = layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: cellAttributes.indexPath) { attributesInRect.append(supplementaryAttributes) } } } } return attributesInRect } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return cellAttrsDictionary[indexPath]! } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true } override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { if elementKind == UICollectionElementKindSectionHeader { let atts = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, with: indexPath) if let itemAttributes = layoutAttributesForItem(at: indexPath) { // HERE WE HAVE TO SET FRAME FOR SUPPLEMENTARY VIEW atts.frame = CGRect(x: itemAttributes.frame.origin.x, y: itemAttributes.frame.origin.y - CGFloat(headerSpacing),width: itemAttributes.frame.width,height: CGFloat(headerSpacing)) return atts } } return nil } } 

XIB子类 – [收集可重用视图]

在此处输入图像描述

 class RulesReusableView: UICollectionReusableView { @IBOutlet weak var headLbl: UILabel! } 

UICollectionViewCell

 class RulesCollectionViewCell: UICollectionViewCell { @IBOutlet weak var txtLbl: UILabel! } 

纵向输出

在此处输入图像描述

景观输出

在此处输入图像描述