0

I having recently implemented a solution that allows me to know when a scroll view has finished scrolling. This is so that when I scroll my tableview I only call a specific method once the tableview has stopped moving completely.

I followed the answer provided here :https://stackoverflow.com/a/8010066/2126233 but am including code below for ease of reading:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    self.isScrolling = YES;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //[super scrollViewDidEndDragging:scrollView willDecelerate:decelerate];    // pull to refresh

    if(!decelerate) {
        self.isScrolling = NO;
        [self callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn];
    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    self.isScrolling = NO;
    [self callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn];
}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{   
    self.isScrolling = NO;
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
        self.isScrolling = NO;
}

This solution works perfectly. However I require this same logic in 4 different view controllers and I don't like having duplicate code.

I am unsure how I can implement the code above in one class and then use it in the other 4 classes.

I have had a few ideas:

  • I have a base class that all other view controllers inherit from. I was thinking I could subclass the base class and then the 4 view controls that require this code are subclassed from this new class. This new class provides the implementation for the scroll delegate methods. But how do I call the method and passing in the tableView and dataArray.

  • Subclassing UITableView and in the subclass implementing these 4 methods. This means I could pass in the tableView ok. But the data source is array is a little more problematic.

Does anyone have any suggestions on an elegant way this issue can be solved. Many thanks

Community
  • 1
  • 1
pls
  • 1,522
  • 2
  • 21
  • 41
  • If that method that requires table view and array is also needed than you can move this code to the base class. If on the other hand this array is only specific to this view controller than you can override scrollViewDidEndDecelerating and call super in it and do your thing. Third idea that comes to my mind is that you could create a new class that would implement those method and during initialisation you would pass as arguments the table view and the array. It's really hard for me to guess what's the structure of your objects :) – sloik Aug 09 '15 at 11:11

1 Answers1

0

I think you are on right track

I have a base class that all other view controllers inherit from. I was thinking I could subclass the base class and then the 4 view controls that require this code are subclassed from this new class. This new class provides the implementation for the scroll delegate methods.

Now your question is

how do I call the method and passing in the tableView and dataArray

For this you can take help of delegate methods In your base class make a protocol

In yourBaseClass.h

@protocol  MyDelegate <NSObject>
@required
-(void)callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn;
@end   

@interface yourBaseClass:UITableViewController
@property (nonatomic, weak) id<MyDelegate> myDelegate;
@end 

In yourBaseClass.m

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    self.isScrolling = YES;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //[super scrollViewDidEndDragging:scrollView willDecelerate:decelerate];    // pull to refresh

    if(!decelerate) {
        self.isScrolling = NO;
       if(self.myDelgate && [self.myDelegate respondsToSelector(callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn)])
        {
            [self.myDelegate callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn];
        }

    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    self.isScrolling = NO;
    if(self.myDelgate && [self.myDelegate respondsToSelector(callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn)])
    {
        [self.myDelegate callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn];
     }

}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
  {   
      self.isScrolling = NO;
  }

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
  {
      self.isScrolling = NO;
  }

Now you have to just implement the myDelegate method callMethodThatRequiresTableViewAndArrayOfDataToBePassedIn in your subclasses.

And yes also set the

self.myDelegate=self;

in your subclass viewDidLoad method.

With this approach you need not to pass any tableView or dataArray.

Hope this helps.

SandeepAggarwal
  • 1,273
  • 3
  • 14
  • 38