views:

235

answers:

1

Hi all -

I have a UIScrollView that houses a gallery of images the user can scroll through. This view needs to be visible on each of three separate UIViewControllers that are housed within a UITabBarController. Right now, I have three separate UIScrollView instances in the UITabBarController subclass, and the controller manages keeping the three synchronized (when a user scrolls the one they can see, programmatically scrolling the other two to match, etc.), which is not ideal.

I would like to know if there is a way to work with only ONE instance of the UIScrollView, but have it show up only in the UIViewController that the user is currently interacting with. This would completely eliminate all the synchronization code. Here is basically what I have now in the UITabBarController (which is where all this is currently managed):

@interface ScrollerTabBarController : UITabBarController {
  FirstViewController *firstView;
  SecondViewController *secondView;
  ThirdViewController *thirdView;

  UIScrollView *scrollerOne;
  UIScrollView *scrollerTwo;
  UIScrollView *scrollerThree;
}
@property (nonatomic,retain) IBOutlet FirstViewController *firstView;
@property (nonatomic,retain) IBOutlet SecondViewController *secondView;
@property (nonatomic,retain) IBOutlet ThirdViewController *thirdView;
@property (nonatomic,retain) IBOutlet UIScrollView *scrollerOne;
@property (nonatomic,retain) IBOutlet UIScrollView *scrollerTwo;
@property (nonatomic,retain) IBOutlet UIScrollView *scrollerThree;

@end

@implementation ScrollerTabBarController

- (void)layoutScroller:(UIScrollView *)scroller {}
- (void)scrollToMatch:(UIScrollView *)scroller {}

- (void)viewDidLoad {
  [self layoutScroller:scrollerOne];
  [self layoutScroller:scrollerTwo];
  [self layoutScroller:scrollerThree];

  [scrollerOne setDelegate:self];
  [scrollerTwo setDelegate:self];
  [scrollerThree setDelegate:self];

  [firstView setGallery:scrollerOne];
  [secondView setGallery:scrollerTwo];
  [thirdView setGallery:scrollerThree];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  [self scrollToMatch:scrollView];
}

@end

The UITabBarController gets notified (as the scroll view's delegate) when the user scrolls one of the instances, and then calls methods like scrollToMatch: to sync up the other two with the user's choice.

Is there something that can be done, using a many-to-one relationship on IBOutlet or something like that, to narrow this down to one instance so I'm not having to manage three scroll views? I tried keeping a single instance and moving the pointer from one view to the next using the UITabBarControllerDelegate methods (calling setGallery:nil on the current and setGallery:scrollerOne on the next each time it changed), but the scroller never moved to the other tabs.

Thanks in advance!

A: 

Certainly you should use only one instance of your scroller view. And it will works fine without any troubles. Use method setGallery: like you did, just ensure you add your singleScrollerForAll view to view of current controller in setGallery method:

-(void)setGallery:(UIView *)aScrollerView{
    [self.view addSubview:aScrollerView];
}

and call:

[firstView setGallery:singleScrollerForAll];

or

[secondView setGallery:singleScrollerForAll];

and no need to do anything in other two controllers, because when you call addSubview: the subView will be automatically removed from previous superview.

Vladimir
Vladimir -Thanks so much for the insights. That works perfectly.Your affirmation led me to look into it more deeply to discover that my implementation was flawed in assigning each UIScrollView as IBOutlet. Even though I tried to move the pointers around, with the IBOutlet connections still in place, it was futile.Once I got that out of my head and used addSubView, life was good.
Wireless Designs