Search code examples
iosswiftiphoneuikit

Image Zoom not working in a UIScrollView inside a Root UIScrollView


I'm trying to zoom an image that is inside a UIScrollView, and that UIScrollView it's inside of a root UIScrollView that allow paging, similar to the Photos app.

In the viewDidLoad() inside the view that contains the root scrollView I call prepareScrollView()

    func prepareScrollView(){

      let tap = UITapGestureRecognizer(target: self, action: #selector(hideNavigationItem))


      scrollView.addGestureRecognizer(tap)

      scrollView.delegate = self
      scrollView.minimumZoomScale = 1.0
      scrollView.maximumZoomScale = 4.0
      scrollView.zoomScale = 1.0


      let width = self.view.bounds.width
      let height = self.view.bounds.height
      totalWidth = width * CGFloat((imageArray!.count)!) //The width must be the width of the screen by the number of the images in the array
      scrollView.contentSize = CGSize(width: totalWidth, height: height)
      scrollView.isPagingEnabled = true

      loadPages()

}

The loadPages() function load every scrollView with their image and add it to the root scrollview.

func loadPages(){

    for i in 0...((imageArray!.count)! - 1){

        let pageScroll = Page(frame: CGRect(x: self.view.bounds.size.width * CGFloat(i), y: self.view.frame.origin.y, width: self.view.bounds.size.width, height: self.view.bounds.size.height))

        pageScroll.minimumZoomScale = 1.0
        pageScroll.maximumZoomScale = 4.0
        pageScroll.zoomScale = 1.0

        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
        imageView.image = UIImage(data: (imageArray![i])!)
        imageView.contentMode = .scaleToFill
        pageScroll.addSubview(imageView)

        scrollView.addSubview(pageScroll)
    }
}

The Page object it's just a UIScrollView object.

class Page: UIScrollView {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return self.subviews[0]//Return the image
}

}

And inside the root scrollView viewForZooming function it calls the viewForZooming function of the correspond child scrollview.

func viewForZooming(in scrollView: UIScrollView) -> UIView? {

    if(self.scrollView.subviews.count > 0){
        let childScrollView = self.scrollView.subviews[currentPage] as! Page
        let image = childScrollView.viewForZooming(in: scrollView)
        return image
    }
    return nil
}

With this approach I can navigate horizontally but I can't zoom in the current image. The viewForZooming function executes in both objects. What I'm doing wrong?


Solution

  • Finally I solve my issue. I changed the Page object to a simple UIScrollView and then set the delegate of the scrollView object to self.

    func loadPages(){
    
        for i in 0...((comic?.comicsPages!.count)! - 1){
    
            let pageScroll = UIScrollView(frame: CGRect(x: self.view.bounds.size.width * CGFloat(i), y: self.view.frame.origin.y, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
    
            pageScroll.minimumZoomScale = 1.0
            pageScroll.maximumZoomScale = 4.0
            pageScroll.zoomScale = 1.0
            pageScroll.isUserInteractionEnabled = true
            pageScroll.delegate = self //Here
    
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
            imageView.image = UIImage(data: (imageArray![i])!)
            imageView.contentMode = .scaleToFill
    
            pageScroll.addSubview(imageView)
    
            scrollView.addSubview(pageScroll)
        }
    }
    

    And then in the viewForZooming function of the root scrollView I change the code for this:

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    
        if(scrollView.subviews.count > 0){
            return scrollView.subviews[0]
        }
        return nil
    }
    

    The scrollView parameter is the child scrollview so it works as expected.