简体   繁体   中英

UICollectionView resets content offset after scrolling a nested UITableView

Setup:

I have a single UICollectionView created on a Storyboard and delegates connected to a controller, oriented for horizontal scroll. Each UICollectionViewCell has a UITableView inside, delegated to the same controller. The Collection view is paged. There are about 3.5 cells visible at a time.

Problem:

If I scroll over horizontally on the collection view so that is now "paged" over 1 length, and then attempt to scroll a contained UITableView vertically, the UICollectionView UNINTENTIONALLY content offset resets by animating to content offset of 0,0. The touch event is maintained, and the dequeued cell continues its scrolling action. I do not want the collection view to reset when a user scrolls the tableview

note:

using the iPad simulators

样本图片 Here is a sample picture. Each column is a UICollectionViewCell containing a UITableView. Each row within the column is a UITableViewCell. If I am not at Content off set of 0,0 for the UICollectionView, and I scroll on any TableView, the collection view animates back to having a content offset of 0,0

Little bit outdated answer, but might help someone. First set scrollView delegate in collectionView to return to main view controller.

Declare in view controller:

private var scrollViewOffset: CGPoint = CGPointZero

In main view controller add the following code:

func scrollViewDidScroll(scrollView: UIScrollView) {

        if scrollView == self.tableView {
            return
        }

        self.scrollViewOffset = scrollView.contentOffset

        for cell in self.tableView.visibleCells {
            (cell as! MyCell).collectionView.contentOffset = scrollView.contentOffset
        }
    }

After you did this part, next one is what you're missing:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: MyCell = tableView.dequeueReusableCellWithIdentifier("CellID", forIndexPath: indexPath) as! MyCell           
        cell.delegate = self

        cell.collectionView.reloadData()
        cell.collectionView.layoutIfNeeded() // THIS PART IS NEEDED IN ORDER NOT TO SCROLL TO 0, 0 OFFSET
        return cell
    }

And in:

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        let cell: MyCell = cell as! MyCell
        cell.collectionView.contentOffset = self.scrollViewOffset
    }

Content of the MyCell should be something like this:

protocol MyCellDelegate {
        func scrollViewDidScroll(scrollView: UIScrollView)
    }
    class MyCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
    var delegate: MyCellDelegate? = nil

// Do collection view display logic here
// ...
// After that implement scrollview delegate

    func scrollViewDidScroll(scrollView: UIScrollView) {
            if (self.delegate != nil) {
                self.delegate?.scrollViewDidScroll(scrollView)
            } else {
                print("Missing delegate init")
            }
        }
}

This answer is for Xcode 7.3

Nested scroll views have undefined scroll behavior in iOS last time I checked. You may be able to override behavior to suit your purposes by extending (or subclassing) the table or collection views and ignoring certain events by checking the sender (or sender's identifier) in content mutator methods.

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