0
1

More than 3 years have passed since last update.

item 数により自動レイアウトするUICollectionViewを作ってみる

Last updated at Posted at 2021-03-08
import UIKit

let kCellWidth1 = CGFloat(130)
let kCellWidth2 = CGFloat(110)
let kCellHeight = CGFloat(104)

let kMiniumSpacing = CGFloat(10)

class ViewController: UIViewController {
    var myCollectionView:UICollectionView?
    var scrWidth = CGFloat(0);
    var itemCount = 2

    override func viewDidLoad() {
        super.viewDidLoad()

        scrWidth = self.view.bounds.width
        setupCollection()
        setupTextInput()
    }

    func getRowItemCount() -> Int {
        let viewWidth = self.scrWidth
        let itemWidth = getItemSize().width
        let minPadding = getSectionInset().left
        let minItemSpacing = getMinItemSpacing()
        let rowCount = Int((viewWidth - minPadding * 2 + minItemSpacing) / (itemWidth + minItemSpacing))
        return rowCount
    }

    func getColumnItemCount() -> Int {
        let rowCount = getRowItemCount()
        guard rowCount > 0 else {
            return 0
        }
        let columnCount = Int(ceil(Double(itemCount) / Double(rowCount)))
        return columnCount
    }

    func getCollectionHeight() -> CGFloat {
        let itemHeight = getItemSize().height
        let columnCount = getColumnItemCount()
        let inset = getSectionInset()
        let lineSpacing = getMinLineSpacing()

        let height = itemHeight * CGFloat(columnCount)
                                + (inset.top + inset.bottom)
                                + lineSpacing * CGFloat(columnCount - 1)
        return height
    }

    func getSectionInset() -> UIEdgeInsets {
        var insets = UIEdgeInsets.zero
        let itemWidth = getItemSize().width
        let itemsWidth = CGFloat(itemCount) * itemWidth + CGFloat(itemCount - 1) * getMinItemSpacing()
        let totalWidth = itemsWidth + 2 * kMiniumSpacing
        if totalWidth < self.scrWidth {
            let newPadding = (self.scrWidth - itemsWidth) / 2.0 - 5
            insets = UIEdgeInsets(top: kMiniumSpacing, left: newPadding, bottom: kMiniumSpacing, right: newPadding)
        } else {
            insets = UIEdgeInsets(top: kMiniumSpacing, left: kMiniumSpacing, bottom: kMiniumSpacing, right: kMiniumSpacing)
        }
        return insets
    }

    func getItemSize() -> CGSize {
        let size = self.scrWidth > 375 ? CGSize(width: kCellWidth1, height: kCellHeight) :CGSize(width: kCellWidth2, height: kCellHeight)
        return size
    }

    func getMinItemSpacing() -> CGFloat {
        return 1
    }

    func getMinLineSpacing() -> CGFloat {
        return kMiniumSpacing
    }

    func setupCollection() {
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = getSectionInset()
        layout.itemSize = getItemSize()
        layout.minimumInteritemSpacing = getMinItemSpacing()
        layout.minimumLineSpacing = getMinLineSpacing()
        layout.scrollDirection = .vertical

        let collectHeight = getCollectionHeight()
        let collectionRect =
            CGRect(origin: CGPoint(x: 0, y: 50),
                   size:CGSize(width: scrWidth, height: collectHeight))
        myCollectionView = UICollectionView(frame: collectionRect, collectionViewLayout: layout)
        myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: CollectionCell.cellIdentifier)
        myCollectionView?.backgroundColor = UIColor.link

        myCollectionView?.dataSource = self
        myCollectionView?.delegate = self
        self.view.addSubview(myCollectionView ?? UICollectionView())
    }

    func setupTextInput() {
        let myTextField = UITextField(frame: CGRect(x: 50, y: (view.bounds.height - 80),
                                               width: 300.00, height: 30.00));
        myTextField.placeholder = "pleae enter item count"
        myTextField.backgroundColor = .link
        myTextField.keyboardType = .numbersAndPunctuation
        myTextField.delegate = self
        self.view.addSubview(myTextField)
    }

    func updateCollection() {
        myCollectionView?.frame.size.height = getCollectionHeight()
        if let layout = myCollectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.sectionInset = getSectionInset()
            layout.itemSize = getItemSize()
            layout.minimumInteritemSpacing = getMinItemSpacing()
            layout.minimumLineSpacing = getMinLineSpacing()
            layout.scrollDirection = .vertical
        }
        myCollectionView?.reloadData()
    }
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return itemCount
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionCell.cellIdentifier, for: indexPath)
        myCell.backgroundColor = UIColor.blue
        return myCell
    }
}

extension ViewController: UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
       print("User tapped on item \(indexPath.row)")
    }
}
extension ViewController: UITextFieldDelegate {

//    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//        guard let newValue = Int(string) else {
//            print("変換できません")
//            return true
//         }
//        itemCount = newValue
//        updateCollection()
//        return true
//    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        guard let newValue = Int(textField.text ?? "") else {
            print("変換できません")
            return false
         }
        self.view.endEditing(true)
        itemCount = newValue
        updateCollection()
        return true
    }

}

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1