How to set UICollectionViewCell Width and Height programmatically

后端 未结 20 1031
终归单人心
终归单人心 2020-12-04 08:06

I am trying to implement a CollectionView. When I am using Autolayout, my cells won\'t change the size, but their alignment.

Now I would rather want to

相关标签:
20条回答
  • 2020-12-04 08:47

    swift 4.1

    You have 2 ways in order to change the size of CollectionView.
    First way -> add this protocol UICollectionViewDelegateFlowLayout
    for In my case I want to divided cell into 3 part in one line. I did this code below

    extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource ,UICollectionViewDelegateFlowLayout{
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
        {
                // In this function is the code you must implement to your code project if you want to change size of Collection view
                let width  = (view.frame.width-20)/3
                return CGSize(width: width, height: width)
        }
    
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return collectionData.count
        }
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath)
            if let label = cell.viewWithTag(100) as? UILabel {
                label.text = collectionData[indexPath.row]
            }
            return cell
        }
    }
    

    Second way -> you don't have to add UICollectionViewDelegateFlowLayout but you have to write some code in viewDidload function instead as code below

    class ViewController: UIViewController {
    @IBOutlet weak var collectionView1: UICollectionView!
            var collectionData = ["1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.", "9.", "10.", "11.", "12."]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let width = (view.frame.width-20)/3
            let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
            layout.itemSize = CGSize(width: width, height: width) 
        }
    }
    


    extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    
    
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return collectionData.count
        }
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath)
            if let label = cell.viewWithTag(100) as? UILabel {
                label.text = collectionData[indexPath.row]
            }
    
            return cell
        }
    }
    

    Whatever you write a code as the first way or second way you will get the same result as above. I wrote it. It worked for me

    0 讨论(0)
  • 2020-12-04 08:48

    If, like me, you need to keep your custom flow layout's itemSize dynamically updated based on your collection view's width, you should override your UICollectionViewFlowLayout's prepare() method. Here's a WWDC video demoing this technique.

    class MyLayout: UICollectionViewFlowLayout {
        
        override func prepare() {
            super.prepare()
            
            guard let collectionView = collectionView else { return }
            
            itemSize = CGSize(width: ..., height: ...)
        }
        
    }
    
    0 讨论(0)
  • 2020-12-04 08:49

    #Absolutely simple way:

    class YourCollection: UIViewController,
         UICollectionViewDelegate,
         UICollectionViewDataSource {
    

    #You must add "UICollectionViewDelegateFlowLayout" or, there is no autocomplete:

    class YourCollection: UIViewController,
         UICollectionViewDelegate,
         UICollectionViewDataSource,
         UICollectionViewDelegateFlowLayout {
    

    #Type "sizeForItemAt...". You're done!

    class YourCollection: UIViewController,
         UICollectionViewDelegate,
         UICollectionViewDataSource,
         UICollectionViewDelegateFlowLayout {
     
         func collectionView(_ collectionView: UICollectionView,
          layout collectionViewLayout: UICollectionViewLayout,
          sizeForItemAt indexPath: IndexPath) -> CGSize {
         
         return CGSize(width: 37, height: 63)
    }
    

    That's it.

    Example, if you want "each cell fills the whole collection view":

         guard let b = view.superview?.bounds else { .. }
         return CGSize(width: b.width, height: b.height)
    
    0 讨论(0)
  • 2020-12-04 08:50

    If one is using storyboard and overriding UICollectionViewDelegateFlowLayout then in swift 5 and Xcode 11 also set Estimate size to None

    0 讨论(0)
  • 2020-12-04 08:52

    Size ratio according to iPhone size :

    Here's what you can do to have different width and height for cell's regarding the iPhone size :

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let width = (self.view.frame.size.width - 12 * 3) / 3 //some width
        let height = width * 1.5 //ratio
        return CGSize(width: width, height: height)
    }
    

    And maybe you should also disable your AutoLayout constraints on cell for this answer to work.

    0 讨论(0)
  • 2020-12-04 08:52

    in Swift3 and Swift4 you can change cell size by adding UICollectionViewDelegateFlowLayout and implementing it's like this :

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            return CGSize(width: 100, height: 100)
        }
    

    or if create UICollectionView programmatically you can do it like this :

        let layout = UICollectionViewFlowLayout()
                        layout.scrollDirection = .horizontal //this is for direction
                        layout.minimumInteritemSpacing = 0 // this is for spacing between cells
                        layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height) //this is for cell size
    let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
    
    0 讨论(0)
提交回复
热议问题