7

I have a UIScrollView that loads three different pages.
When i zoom in on a page, and zoom back out to the original size, the application stops letting me scroll between the pages, as if paging is disabled. What can i do to re-enable paging when zoomed out to the original size (Scale == 1)?

This is my code

- (void)viewDidLoad
{
    [ScView setMaximumZoomScale : 2.0f];
    [ScView setMinimumZoomScale : 1.0f];

    ScView.contentSize = CGSizeMake(1024*3, 1.0);
    ScView.pagingEnabled = YES;

    ScView.clipsToBounds = YES;
    ScView.delegate = self;

    ScView.showsHorizontalScrollIndicator = NO;
    ScView.showsVerticalScrollIndicator = NO;

    [super viewDidLoad]; 

    [self returnImages];
}

-(void)returnImages{
    for (pageNumber = 1; pageNumber <= 3; pageNumber++) {
        imagen = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png",pageNumber]]];
        imagen.frame = CGRectMake((pageNumber-1)*1024, 0, 1024, 768);

        [ScView addSubview:imagen];
    }
}

//
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
        return ScView;
   //   return [imagen initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png",pageNumber]]];
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)myScrollView withView:(UIView *)view
{ 
    NSLog(@"Scroll Will Begin");
    ScView.scrollEnabled = YES;
}

- (void)scrollViewDidEndZooming:(UIScrollView *)myScrollView withView:(UIView *)view atScale:(float)scale 
{ 
    if(scale == 1)
    {
        ScView.scrollEnabled = YES;
        ScView.pagingEnabled = YES;
        [self returnImages];
        NSLog(@"Scrolol will end");
        //ScView.maximumZoomScale = 2.0f;
       // [super viewDidLoad];

        [self returnImages];
    }
}

Any ideas will be highly appreciated..

Elias Rahme
  • 2,226
  • 3
  • 28
  • 53

2 Answers2

19

To get proper paging and zooming you have to embed UIScrollView for each page into your parent UIScrollView. This combination will allow you to use simultaneously paging and internal scrolling.

Here is the example of UIViewController with parent scroll view and three embedded zoomable pages.

#define VIEW_FOR_ZOOM_TAG (1)

@implementation SVViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIScrollView *mainScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    mainScrollView.pagingEnabled = YES;
    mainScrollView.showsHorizontalScrollIndicator = NO;
    mainScrollView.showsVerticalScrollIndicator = NO;

    CGRect innerScrollFrame = mainScrollView.bounds;

    for (NSInteger i = 0; i < 3; i++) {
        UIImageView *imageForZooming = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"page%d", i + 1]]];
        imageForZooming.tag = VIEW_FOR_ZOOM_TAG;

        UIScrollView *pageScrollView = [[UIScrollView alloc] initWithFrame:innerScrollFrame];
        pageScrollView.minimumZoomScale = 1.0f;
        pageScrollView.maximumZoomScale = 2.0f;
        pageScrollView.zoomScale = 1.0f;
        pageScrollView.contentSize = imageForZooming.bounds.size;
        pageScrollView.delegate = self;
        pageScrollView.showsHorizontalScrollIndicator = NO;
        pageScrollView.showsVerticalScrollIndicator = NO;
        [pageScrollView addSubview:imageForZooming];

        [mainScrollView addSubview:pageScrollView];

        if (i < 2) {
            innerScrollFrame.origin.x += innerScrollFrame.size.width;
        }
    }

    mainScrollView.contentSize = CGSizeMake(innerScrollFrame.origin.x + innerScrollFrame.size.width, mainScrollView.bounds.size.height);

    [self.view addSubview:mainScrollView];
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return [scrollView viewWithTag:VIEW_FOR_ZOOM_TAG];
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotate {
    return NO;
}

@end
Narmo
  • 595
  • 4
  • 11
2

I follow @NikNarmo 's solution, write a small swift xcode project to demo the zooming and paging function.

Hope to help anyone who want to do the same task.

Some code is from UIScrollView Tutorial: Getting Started http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift,

and some from A Beginner’s Guide to UIScrollView http://www.appcoda.com/uiscrollview-introduction/.

Using Xcode 7.0 and Swift 2.0

  override func viewDidLoad() {

    super.viewDidLoad()

    mainScrollView = UIScrollView(frame: self.view.bounds)
    mainScrollView.pagingEnabled = true
    mainScrollView.showsHorizontalScrollIndicator = false
    mainScrollView.showsVerticalScrollIndicator = false

    pageScrollViews = [UIScrollView?](count: photos.count, repeatedValue: nil)

    let innerScrollFrame = mainScrollView.bounds

    mainScrollView.contentSize =
        CGSizeMake(innerScrollFrame.origin.x + innerScrollFrame.size.width,
            mainScrollView.bounds.size.height)

    mainScrollView.backgroundColor = UIColor.redColor()
    mainScrollView.delegate = self
    self.view.addSubview(mainScrollView)

    configScrollView()
    addPageControlOnScrollView()
}

and the magic is in the func scrollViewWillEndDragging, when the contentSize is equal to the mainScrollViewContentSize or not, if it is mainScrollViewController, then do paging, otherwise do nothing.

  func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

    let targetOffset = targetContentOffset.memory.x
    let zoomRatio = scrollView.contentSize.height / mainScrollViewContentSize.height

    if zoomRatio == 1 {
        // mainScrollViewController
        let mainScrollViewWidthPerPage = mainScrollViewContentSize.width / CGFloat(pageControl.numberOfPages)

        let currentPage = targetOffset / (mainScrollViewWidthPerPage * zoomRatio)
        pageControl.currentPage = Int(currentPage)
        loadVisiblePages()

    }
    else {
        // pageScorllViewController
    }
}

And here is the project code https://github.com/Charles-Hsu/ScrollViewDemo

charles.cc.hsu
  • 689
  • 11
  • 15
  • How to connect the Swift code to storyboard? I downloaded your whole project code but and noticed your storyboard is just a View Controller. – user2872856 Dec 24 '15 at 07:44
  • This is my question: http://stackoverflow.com/questions/34449359/zoom-images-in-paged-uiscrollview – user2872856 Dec 24 '15 at 08:22
  • There is a problem. I couldn't add Admob to the scrollview. Please help. http://stackoverflow.com/questions/34460756/loading-admob-without-using-storyboard-swift/34460786 – user2872856 Dec 25 '15 at 07:32
  • I faced another problem. How to start the paging at specific page? http://stackoverflow.com/questions/34463298/set-initial-page-of-uiscrollview-using-swift – user2872856 Dec 25 '15 at 13:34
  • @user2872856 call gotoPage(page: Int) in viewDidLoad. – charles.cc.hsu Dec 26 '15 at 05:34