Ios UICollectionView在UITableViewCell中的重用

Ios UICollectionView在UITableViewCell中的重用,ios,swift,uitableview,uicollectionview,Ios,Swift,Uitableview,Uicollectionview,我知道这个问题已经被问了很多次了,但没有一个解决方案能奏效 我在uitableview单元格中有集合视图,我在故事板中准备了一个表格视图和集合视图单元格,我的问题是,假设我滚动单元格1集合视图,那么单元格4集合也会自动滚动到该位置。我如何处理这种情况 请注意,现在我做了一个屏幕的静态设计 我的代码 // MARK: // MARK: table view delegate method func numberOfSectionsInTableView(tableView: UI

我知道这个问题已经被问了很多次了,但没有一个解决方案能奏效

我在uitableview单元格中有集合视图,我在故事板中准备了一个表格视图和集合视图单元格,我的问题是,假设我滚动单元格1集合视图,那么单元格4集合也会自动滚动到该位置。我如何处理这种情况

请注意,现在我做了一个屏幕的静态设计

我的代码

// 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单元代码

我滚动的第一个单元格

自动滚动的第四个单元格


有两种情况

1-重置UICollectionView偏移位置:

要重置collectionview位置,只需在cellForRowAtIndexPath中调用cell.collectionview.contentOffset=.zero

2-保持上一个滚动位置:


要保持上一个滚动位置,需要在包含视图控制器的数据模型旁边存储每个单元格的偏移列表。然后,您可以将给定单元格的偏移量保存在
didendisplayingcell
中,并在
cellForRowAtIndexPath
中设置它,而不是
。zero
UITableView
基于
可重用性的概念。每当滚动
tableView
时,
tableView
中的
单元格肯定会被重用

现在出现了两种情况

  • 获取一个新单元格-当重用
    tableViewCell
    时,其中的
    集合视图
    也将被重用,因此这就是保留上一个单元格的
    内容偏移量
    的原因

  • 滚动到上一个单元格
    -如果在
    集合视图
    中手动滚动到特定的
    单元格
    ,我们可能希望在滚动回该单元格时保留其位置

  • 要在
    tableView
    中获得此类功能,我们需要手动重置
    第一种情况下的
    contentOffset
    ,并需要在第二种情况下保留
    contentOffset

    您可以遵循的另一种方法是使用UIScrollview和UIStackView的组合

    事情就是这样

  • 在故事板中创建UIScrollView。向其中添加垂直视图

  • stackView
    中添加4个
    uicollectionview
    。此号码可根据您的要求进行配置

  • 将您的
    控制器
    添加为所有
    集合视图的
    数据源
    委托

  • i、 e

    现在,由于我们使用的是
    stackView
    ,因此不会重用
    collectionview
    。所以,所有
    collectionview
    contentoffset
    将保持不变


    看起来像这4个。重新分配牢房并从牢房1中取出所有物品。这是正确的,您必须对重用做出反应。在单元格类中,您需要重写func“prepareforeuse”,在那里您应该重置内容、滚动位置或whatever@Bj但它也会对实际的滚动单元格产生影响。我不认为这是解决方案是的,这是真的,但这就是它的工作原理。如果您的单元格超出屏幕,那么它将被重新用于新单元格。因此,它将使用之前单元格中的所有内容。执行此操作时,您只需存储每个集合视图的偏移位置,并在每次重新加载表视图时进行设置。在prepareforreuse中,重置集合视图的偏移量对于第一个场景,我使用prepareforreuse函数。感谢您的建议。如果集合视图数不同,则可能很难管理此解决方案。在这种情况下,您需要创建一个集合视图数组,然后遍历它以填充堆栈视图。它似乎完全超越了表视图的用途,不是吗?当然,这是唯一的缺点。在这种方法中,一切都必须手动处理。
    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
        }
    
    }
    
    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!
    }