简体   繁体   English

UICollectionView在UITableViewCell中重用

[英]UICollectionView reuse in UITableViewCell

I know this question is already ask many times but non of the solution will work. 我知道这个问题已经问了很多次,但是没有解决方案可行。

I have collection view in uitableview cell and i prepare a cell of table view and collection view in story board and my problem is that suppose i scroll cell 1 collection view then cell 4 collection is auto scroll to that position also. 我在uitableview单元格中有集合视图,我在故事板中准备了一个表视图和集合视图的单元格,我的问题是假设我滚动单元格1集合视图,然后单元格4集合也自动滚动到该位置。 How i can handle this situation.. 我怎么能处理这种情况..

Please note right now i make a static design of the screen 请注意我现在制作一个静态的屏幕设计

My code 我的代码

// MARK:
    // MARK: table view delegate method

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        if Appconstant.isIpad()
        {
            return 215.0
        }
        return 185.0

    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 6
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let strCell = "WorkoutCell" //+ "\(indexPath.row)"
        let cell = tableView.dequeueReusableCellWithIdentifier(strCell) as? WorkoutCell
//        if cell == nil
//        {
//            cell = work 
//        }
        return cell!
    }
    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        let cell2 = cell as! WorkoutCell
        cell2.collecionWorkout.reloadData()
    }
    // MARK:
    // MARK: collectionview delegate and data source
    //1
    func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
        return true
    }
     func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    //2
     func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0)
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: NSIndexPath) -> CGSize {
        // Adjust cell size for orientation
        if Appconstant.isIpad() {
            return CGSize(width: 160, height: 150)
        }
        return CGSize(width: 140.0, height: 130.0)
    }
    //3
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("WorkoutCollectionCell", forIndexPath: indexPath)
        // Configure the cell
        return cell
    }

uitableview cell code uitableview单元格代码

class WorkoutCell: UITableViewCell {

    @IBOutlet weak var collecionWorkout: UICollectionView!
    var flowLayout : UICollectionViewFlowLayout!
    override func awakeFromNib() {
        super.awakeFromNib()
        self.flowLayout = UICollectionViewFlowLayout()
        if Appconstant.isIpad()
        {
            self.flowLayout.itemSize = CGSize(width: 160, height: 150)
        }
        else
        {
            self.flowLayout.itemSize = CGSize(width: 140, height: 130)
        }
        self.flowLayout.scrollDirection = .Horizontal
        self.flowLayout.minimumInteritemSpacing = 10.0
        flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0);
        collecionWorkout.collectionViewLayout = flowLayout

        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Cell 1st which i scroll 我滚动的Cell 1st

在此输入图像描述

cell 4th which auto scroll 单元格4自动滚动

在此输入图像描述

There are two scenarios. 有两种情况。

1 - Reset The UICollectionView offset position : 1 - 重置UICollectionView偏移位置:

To Reset the collectionview position just call cell.collectionView.contentOffset = .zero in cellForRowAtIndexPath 要重置collectionview位置,只需在cellForRowAtIndexPath中调用cell.collectionView.contentOffset = .zero

2 - Maintain the previous scroll position : 2 - 保持上一个滚动位置:

To Maintain the previous scroll position, You'll need to have a list of offsets for each cell stored alongside your data models in the containing view controller. 要保持上一个滚动位置,您需要在包含视图控制器中的数据模型旁边存储每个单元格的偏移列表。 Then you might save the offset for a given cell in didEndDisplayingCell and setting it in cellForRowAtIndexPath instead of .zero . 然后,您可以在didEndDisplayingCell保存给定单元格的偏移量,并将其设置为cellForRowAtIndexPath而不是.zero

UITableView works on the concept of reusability . UITableView致力于reusability的概念。 Whenever the tableView is scrolled, the cells in the tableView will definitely be reused. 每当滚动tableView时, tableView中的cells tableView定会被重用。

Now 2 scenarios arise with this, 现在出现了2个场景,

  1. Get a new cell - When the tableViewCell is reused, the collectionView inside it also will be reused and so this is the reason the contentOffset of the previous cell is retained. 获取一个新单元格 - 当重复使用tableViewCell ,其中的collectionView也将被重用,因此这就是保留前一个单元格的contentOffset的原因。

  2. Scroll to previous cell - if we've manually scrolled to a particular cell in the collectionView , we might want to retain its position when we scroll back to it. Scroll to previous cell - 如果我们手动滚动到collectionView的特定cell ,我们可能希望在滚动回到它时保留其位置。

To get this kind of functionality in tableView , we need to - manually reset the contentOffset for 1st case and need to retain the contentOffset in the 2nd one. 要在tableView获得这种功能,我们需要 - 为1st case手动重置contentOffset ,并且需要在第二种1st case保留contentOffset

Another approach you can follow is using a combination of UIScrollview and UIStackView . 您可以遵循的另一种方法是使用combination of UIScrollview and UIStackViewcombination of UIScrollview and UIStackView

This is how it goes. 这是怎么回事。

  1. In storyboard , create a UIScrollView. storyboard ,创建一个UIScrollView。 Add a vertical UIStackView to it. 添加一个垂直的UIStackView。

  2. Add 4 UICollectionViews in the stackView . UICollectionViews中添加4个stackView This number is configurable as per your requirement. 此编号可根据您的要求进行配置。

  3. Add your controller as the dataSource and delegate of all the collectionViews . controller添加为所有collectionViewsdataSourcedelegate

ie

class ViewController: UIViewController, UICollectionViewDataSource {
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
        cell.label.text = "\(indexPath.row)"
        return cell
    }
}

class CustomCell: UICollectionViewCell {
    @IBOutlet weak var label: UILabel!
}

Now, since we're using a stackView , none of the collectionViews will be reused. 现在,由于我们使用的是stackView ,因此不会重复使用任何collectionViews So, the contentOffsets of the all the collectionViews will remain intact. 因此,所有collectionViewscontentOffsets将保持不变。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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