-1

I have a UIViewController that has UITableView and UICollectionView. I want to do certain tasks when UICollectionView is scrolled.

I've extended UIScrollViewDelegate and wrote my code in

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)

But this method is called when both UITableView and UICollectionView are scrolled. How do I differentiate between the two views here? I tried

  func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

    if let cv = scrollView as? UICollectionView {

    }
  }

But it's not working. I tried po scrollView and the output is <uninitialized>.

Sikander
  • 447
  • 4
  • 26
  • How is your attempt now working? Did you set the `delegate` to `self`? – Sweeper Jan 09 '20 at 07:25
  • `delegate` on `UICollectionView`? I haven't set that delegate specifically but the delegate methods are called on both `UITableView` and `UICollectionView` – Sikander Jan 09 '20 at 07:28
  • How's that possible? How do you know the delegate methods are called? If they are called, how do you know your `if let` statement doesn't work? – Sweeper Jan 09 '20 at 07:30
  • I've set breakpoints in the `delegate` methods, if I remove the `if` statement the code inside is executed on both `UITableView` and `UICollectionView` scrolling. – Sikander Jan 09 '20 at 07:32
  • All you have to do is use the `isKind` protocol with fast enumeration. – El Tomato Jan 09 '20 at 08:31
  • Both TableView & CollectionView are subclasses of UIScrollView , that's why method gets called in both cases. Now to check whether its tableview or collectionView , simply checkyour tableview or collectionview instance against the scrollview instance you get inside ScrollViewDidScroll Method. – Help Jan 09 '20 at 09:02

2 Answers2

1

// Say tv and cv are outlets to table View and Collection View

Objective c

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView == self.tv) {
        self.tv.contentOffset = self.tv.contentOffset;
    } else if (scrollView == self.cv) {
        self.cv.contentOffset = self.cv.contentOffset;
    }
}

Swift

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

    if let scrollView == tv {
         //do whatever you need with tableView
    }
    if let scrollView == cv {
        //do whatever you need with collectionView
    }

  }
Jawad Ali
  • 13,556
  • 3
  • 32
  • 49
0

It was a mistake on my end but for others here I'll post the answer.

I needed to execute my code when slider has finished dragging/scrolling. To achieve that I had

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    NSObject.cancelPreviousPerformRequests(withTarget: self)
    perform(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation), with: nil, afterDelay: 0.3)
}

Problem was in line

perform(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation), with: nil, afterDelay: 0.3)

Instead of passing nil, I wrote

perform(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation), with: scrollView afterDelay: 0.3)

and that resolved it. I wasn't getting scrollView <uninitialized> anymore and my

if let cv = scrollView as? UICollectionView {

}

worked fine.

Sikander
  • 447
  • 4
  • 26