Unexpected behavior with nested collection views w

2020-03-30 16:10发布

问题:

I have a cell in a tableview that contains a horizontal paging collection view.

Inside each page of this collection view there is a vertical collection view.

In order to avoid a "scroll-in-scroll" problem, I disabled vertical scrolling in the vertical collection views.

The vertical collection view's cell count is not static and can be any number.

So this creates a problem: the collection view (you'll have to ask me for clarification about which one) won't fit properly into the table view's cell anymore.

To solve this, I changed the table view's cell height by changing the constraints in the storyboard... but the problem remains.

Here is an image to help illustrate the problem:

and here is my code:

class myTBViewController: UITableViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if collectionView.tag == 10 {
    return 2
    } else {
        return 30
    }
}


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if collectionView.tag == 10 {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mainPages", for: indexPath) as! mainPages

        cell.backgroundColor = UIColor.yellow
        cell.listCV.clipsToBounds = true
    return cell
    } else {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "showAdvCell", for: indexPath) as! showAdvCell

        cell.backgroundColor = UIColor.red

        return cell

    }
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

    if collectionView.tag == 10 {
    let collectionViewHeight = collectionView.frame.height
    let itemsHeight        = collectionView.contentSize.height

    let topInset = ( collectionViewHeight - itemsHeight ) / 4

    return UIEdgeInsetsMake(topInset ,0, 0 , 0)

    } else {

        let collectionViewHeight = collectionView.frame.height
        let itemsHeight        =  CGFloat(80)

        let topInset = ( collectionViewHeight - itemsHeight ) / 4

        return UIEdgeInsetsMake(topInset ,0, 0 , 0)


    }
}

var headerSegment = UISegmentedControl()

override func viewDidLoad() {
    super.viewDidLoad()

    headerSegment.frame = CGRect(x: 0, y: 200, width: UIScreen.main.bounds.width, height: 30)
    let items = ["فروشگاه ها", "دیوار"]
    headerSegment = UISegmentedControl(items: items)
    headerSegment.selectedSegmentIndex = 0
    headerSegment.addTarget(self, action: #selector(selectPage), for: UIControlEvents.valueChanged)
    let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 200)
    let headerImageView = UIImageView(frame: frame)
    let image: UIImage = UIImage(named: "1")!
    headerImageView.image = image

    let frame3 = CGRect(x: 0, y: 0, width: 80, height: 80)
    let headerImageView2 = UIImageView(frame: frame3)
    let image2: UIImage = UIImage(named: "1")!
    headerImageView2.image = image2
    headerSegment.addSubview(headerImageView2)
    headerSegment.bringSubview(toFront: headerImageView2)
    headerImageView2.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: 200)
    headerSegment.frame = CGRect(x: 0, y: 200, width: UIScreen.main.bounds.width + 10 , height: 40)
    headerSegment.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: 200)
    let mainView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 230))
    let headerSegmentView = UIView(frame : CGRect(x: 0, y: 200, width: UIScreen.main.bounds.width, height: 40))
    headerSegmentView.center = headerSegment.center
    headerSegmentView.backgroundColor = UIColor.white
    mainView.addSubview(headerImageView)
    mainView.bringSubview(toFront: headerImageView)
    mainView.addSubview(headerSegmentView)
    mainView.bringSubview(toFront: headerSegmentView)
    mainView.addSubview(headerSegment)
    mainView.bringSubview(toFront: headerSegment)
    mainView.addSubview(headerImageView2)
    mainView.bringSubview(toFront: headerImageView2)
    self.tableView.tableHeaderView = mainView

    headerImageView2.layer.borderWidth = 2
    headerImageView2.layer.masksToBounds = false
    headerImageView2.layer.borderColor = UIColor.init(white: 255/255, alpha: 0.3).cgColor
    headerImageView2.layer.cornerRadius = headerImageView2.frame.height/2
    headerImageView2.clipsToBounds = true

}

@objc func selectPage() {

    let cell = self.tableView.dequeueReusableCell(withIdentifier: "myTBViewCell") as! myTBViewCell

    switch headerSegment.selectedSegmentIndex {
    case 0:
        print("0")
        cell.myTBCollectionView.scrollToItem(at:IndexPath(item: 0, section: 0), at: .top, animated: false)
    case 1:
        print("1")
        cell.myTBCollectionView.scrollToItem(at:IndexPath(item: 1, section: 0), at: .top, animated: false)
    default:
        print("0")
        cell.myTBCollectionView.scrollToItem(at:IndexPath(item: 0, section: 0), at: .top, animated: false)

    }

}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 1
}


override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    tableView.estimatedRowHeight = 200
    tableView.rowHeight = UITableViewAutomaticDimension

    return 600
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "myTBViewCell", for: indexPath) as! myTBViewCell

    return cell
}


}

回答1:

I have similar Problem , finally I have solved it by creating height Constraint of CollectionView.

than setting CollectionView height Constraint based on CollectionView ContentSize.

self.collectionViewHeight.constant = self.recentCollectionView.collectionViewLayout.collectionViewContentSize.height

inaddtion you dont need to return fixed 600 height in your tableview delegate heightForRowAtIndexPath