简体   繁体   中英

SWIFT: How to set the frame size of a collection view programmatically so that it's equal to its parent view?

I am implementing a collectionView programmatically:

class collectionViews {
     static func collectionViewOne() -> UICollectionView {
        let flowLayout = CarouselFlowLayout()
        let collectionViewOne = UICollectionView(frame: CGRect(x: 106, y: 313, width: 1708, height: 300), collectionViewLayout: flowLayout)
        return collectionViewOne
    }
}

I'm displaying it inside a TableViewCell of TableView that's also implemented programatically:

class TableViewCell2: UITableViewCell {
    var moviesItems: [movieItem] = []
    let cellIdentifier = "movieCardCell"
    let collectionViewOne = collectionViews.collectionViewOne()

    private func setupCollectionView(){

        collectionViewOne.delegate = self
        collectionViewOne.dataSource = self
        collectionViewOne.backgroundColor = UIColor (hex: "444A64")
         collectionViewOne.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
                 let nib = UINib(nibName: "movieCardCell", bundle: nil)
        collectionViewOne.register(nib, forCellWithReuseIdentifier: cellIdentifier)
 self.contentView.addSubview(collectionViewOne)

    }
}

// These functions never get called
 extension TableViewCell:  UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
     print("INSIDE TableViewCell2.collectionView 1")
     return 1
 }
 
 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath)
     print("INSIDE TableViewCell2.collectionView 2")
     return cell
 }
 
 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
     // For some reason he chose the measures of collectionViewCell and substracted 2
     print("INSIDE TableViewCell2.collectionView 3")
     return CGSize(width: 139, height: 64)
 }
 }

I want the size frame of the collectionView to be equal to the size of the frame of the TableViewCell : So any idea what should I change here if this is possible?

 let collectionViewOne = UICollectionView(frame: CGRect(x: 106, y: 313, width: 1708, height: 300), collectionViewLayout: flowLayout)

You can set collection view constraints after adding it to a cell inside your setupCollectionView() method:-

//#MARK:- Table view cell
 
class YourTableViewCell: UITableViewCell {
    
    var collectionView: UICollectionView!
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self. setupCollectionView()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    func setupCollectionView() {
        
        //        Set collection view
        let layout = UICollectionViewFlowLayout()
        
        collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        collectionView.backgroundColor = .clear
        collectionView.register(collectionCell.self, forCellWithReuseIdentifier: "collectionCell")
        collectionView.showsVerticalScrollIndicator = false
        collectionView.showsHorizontalScrollIndicator = false
        self.contentView.addSubview(collectionView)
        collectionView.delegate = self
        collectionView.dataSource = self
        
        //Here you can set constraint for collection view
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 0).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: 0).isActive = true
        collectionView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 0).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: 0).isActive = true
        
        layout.scrollDirection = .horizontal
    }
}

In collectionViews.collectionViewOne(), change to:

static func collectionViewOne(frame: CGRect) -> UICollectionView {
        let flowLayout = CarouselFlowLayout()
        let collectionViewOne = UICollectionView(frame: frame, collectionViewLayout: flowLayout)
        return collectionViewOne
    }

and in TableViewCell2 you'll have to change

let collectionViewOne = collectionViews.collectionViewOne()

to

let collectionViewOne: UICollectionView!

and inside of setupCollectionViews()

collectionViewOne = collectionViews.collectionViewOne(frame: bounds)

You have to move it into this function because an instance property cannot rely on self in it's inline declaration, ie you can't pass bounds in the declaration of collectionViewOne.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM