滚动时在行内重用项目

时间:2017-10-19 15:21:46

标签: ios swift uitableview collections uicollectionreusableview

我在 tableView 中有 collectionView collectionView 需要水平滚动图片, tableView 用于垂直滚动帖子。当我有3个时我没有遇到任何问题,但是当我创建4个时,我遇到了在行内滚动的问题。如果我开始在4 上滚动,则在 1上重复滚动,如果我开始滚动1 滚动,则重复滚动 4。

可能是什么问题以及如何解决?可能是

可以检查.gif文件。我从名称“ Oko ”开始1 ,如果我向下滚动4 并向右滚动 collectionCell 并且返回 1 我看到下一个图片名称“城市”,但必须有名称“ Oko

我的代码:

的ViewController:

class PhotoStudiosViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {

    @IBOutlet weak var tableView: UITableView!

    var theStudios: [Studio] = [] 
    var filteredStudios: [Studio] = [] 

    var studiosRef: DatabaseReference!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        tableView.estimatedRowHeight = 475
        tableView.rowHeight = UITableViewAutomaticDimension

    }

    override func viewDidLoad() {
        super.viewDidLoad()

        studiosRef = Database.database().reference(withPath: "PhotoStudios1")

        studiosRef.observe(.value, with: { (snapshot) in

            for imageSnap in snapshot.children {

                let studioObj = Studio(snapshot: imageSnap as! DataSnapshot)

                self.theStudios.append(studioObj)

            }

            self.tableView.reloadData()

        })

    }
    // MARK: - TableView
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if searchController.isActive && searchController.searchBar.text != "" {

            return filteredStudios.count

        }

        return theStudios.count

    }

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

        cell.currentPageNumber.text = "1/\(theStudios[indexPath.row].halls.count)"

        if searchController.isActive && searchController.searchBar.text != nil {
            cell.theHalls = filteredStudios[indexPath.row].halls
        } else {
            cell.theHalls = theStudios[indexPath.row].halls
        }

        cell.nameLabel.text = theStudios[indexPath.row].studioName

        cell.addressLabel.text = theStudios[indexPath.row].studioAddress

        cell.logoLabel.sd_setImage(with: URL(string: theStudios[indexPath.row].studioLogo))

        cell.didSelectAction = {

            (innerPath) in

            self.showDetailsView(indexPath, cellPath: innerPath)

        }

        return cell

    }    

TableViewCell:

class PhotoStudiosTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate, UICollectionViewDelegateFlowLayout {

    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var logoLabel: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var addressLabel: UILabel!
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var currentPageNumber: UILabel!

    var didSelectAction: ((IndexPath) -> ())?

    var theHalls: [Hall] = [] {
        didSet {
            collectionView.reloadData()
        }
    }

    var lastContentOffset = CGPoint.zero 

    override func prepareForReuse() {
        super.prepareForReuse()

        resetCollectionView()

    }

    override func awakeFromNib() {
        super.awakeFromNib()

        currentPageNumber.layer.zPosition = 2
        currentPageNumber.layer.cornerRadius = 15.0
        currentPageNumber.clipsToBounds = true    

    }

    func resetCollectionView() {
        guard !theHalls.isEmpty else { return }
        theHalls = []
        collectionView.reloadData()
    }

    // MARK: - CollectionView
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        return theHalls.count

    }

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

        cell.hallName.text = theHalls[indexPath.item].hallName

        cell.priceLabel.text = theHalls[indexPath.item].hallPrice

        cell.metrslabel.text = theHalls[indexPath.item].hallMetrs

        cell.photoStudioImage.sd_setImage(with: URL(string: theHalls[indexPath.item].hallImage))

        return cell

    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        didSelectAction?(indexPath)

    }

}

git image

1 个答案:

答案 0 :(得分:3)

您正在重复使用单元格中的集合视图,这是正确的,但这意味着当重新使用单元格时,contentOffset也会从之前滚动到的内容中保留。通过执行以下操作设置单元格时,只需重置cell.collectionView.contentOffset = .zero 中的contentOffset就足够了:

lastContentOffset

值得一提的是,我确实看到你的单元格中有一个名为didEndDisplayingCell的属性,但是我还没有做任何事情,我怀疑你会尝试用它来保持给定的偏移量当单元格滚出视图时,您可以在它返回视图时再次设置它(而不是总是重置)。

如果您打算这样做,在单元格中拥有该属性将无法正常工作。您需要在包含视图控制器中的数据模型旁边存储每个单元格的偏移列表。然后,您可以在cellForRowAtIndexPath中保存给定单元格的偏移量,并将其设置为.zero而不是 $i = 0; foreach( $array1 as $key=>$value){ $new_array[$key]=> $array2[$i]; $i++; } ,如上所述。