Stuck understanding how to create a table with multiple columns in iOS Swift

前端 未结 3 1284
借酒劲吻你
借酒劲吻你 2021-02-02 00:47

I\'ve spent the better half of the day so far researching and trying to understand how to make a table with multiple columns. Embarrassingly, I am still quite new to Swift and p

3条回答
  •  走了就别回头了
    2021-02-02 01:19

    IOS 10, XCode 8, Swift 3.0

    I found an awesome tutorial on this. thanks to Kyle Andrews

    I created a vertical table which can be scrollable on both directions by subclassing UICollectionViewLayout. Below is the code.

     class CustomLayout: UICollectionViewLayout {
    
        let CELL_HEIGHT: CGFloat = 50
        let CELL_WIDTH: CGFloat = 180
    
    
        var cellAttributesDictionary = Dictionary()
        var contentSize = CGSize.zero
    
        override var collectionViewContentSize: CGSize {
            get {
                return contentSize
            }
        }
    
        var dataSourceDidUpdate = true
    
        override func prepare() {
    
            let STATUS_BAR_HEIGHT = UIApplication.shared.statusBarFrame.height
            let NAV_BAR_HEIGHT = UINavigationController().navigationBar.frame.size.height
    
            collectionView?.bounces = false
    
            if !dataSourceDidUpdate {
    
                let yOffSet = collectionView!.contentOffset.y
    
                for section in 0 ..< collectionView!.numberOfSections {
                    if section == 0 {
                        for item in 0 ..< collectionView!.numberOfItems(inSection: section) {
                            let cellIndexPath = IndexPath(item: item, section: section)
                            if let attrs = cellAttributesDictionary[cellIndexPath] {
                                var frame = attrs.frame
                                frame.origin.y = yOffSet + STATUS_BAR_HEIGHT + NAV_BAR_HEIGHT
                                attrs.frame = frame
                            }
                        }
                    }
                }
               return
            }
    
            dataSourceDidUpdate = false
    
            for section in 0 ..< collectionView!.numberOfSections {
                for item in 0 ..< collectionView!.numberOfItems(inSection: section) {
                    let cellIndexPath = IndexPath(item: item, section: section)
                    let xPos = CGFloat(item) * CELL_WIDTH
                    let yPos = CGFloat(section) * CELL_HEIGHT
    
                    let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndexPath)
                    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
                    }
    
                    cellAttributesDictionary[cellIndexPath] = cellAttributes
    
                }
            }
    
            let contentWidth = CGFloat(collectionView!.numberOfItems(inSection: 0)) * CELL_WIDTH
            let contentHeight = CGFloat(collectionView!.numberOfSections) * CELL_HEIGHT
            contentSize = CGSize(width: contentWidth, height: contentHeight)
        }
    
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            var attributesInRect = [UICollectionViewLayoutAttributes]()
    
            for cellAttrs in cellAttributesDictionary.values {
                if rect.intersects(cellAttrs.frame) {
                    attributesInRect.append(cellAttrs)
                }
            }
    
            return attributesInRect
        }
    
        override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            return cellAttributesDictionary[indexPath]
        }
    
        override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
            return true
        }
    }
    

    Below is my CollectionViewController Code.

        import UIKit
    
    private let reuseIdentifier = "Cell"
    
    class VerticalCVC: UICollectionViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            collectionView?.isScrollEnabled = true
        }
    
        // MARK: UICollectionViewDataSource
    
        override func numberOfSections(in collectionView: UICollectionView) -> Int {
    
            return 20
        }
    
    
        override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 10
        }
    
        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CustomCell
    
            if indexPath.section == 0 {
                cell.backgroundColor = UIColor.darkGray
                cell.titleLabel.textColor = UIColor.white
    
    
            } else {
                cell.backgroundColor = UIColor.white
                cell.titleLabel.textColor = UIColor.black
            }
    
            cell.titleLabel.text = "section: \(indexPath.section) && row: \(indexPath.row)"
    
            return cell
        }
    }
    

    To force CollectionView to use Custom Layout instead of UICollectionViwFlowLayout check below image.

    Result:

    Portrait mode

    landscape mode

提交回复
热议问题