AnthonyR
AnthonyR

Reputation: 3545

Zoom in UIImageView : View For Zooming is called but nothing happened

I have a problem for zooming in UIImageView.

To understand, my UIViewController have the following structure, very simple :

I just have a collection of images. The screen displays only one image at a time, but to see other images, I can scroll left or right. (Just like the photos app from Apple). I want the zooming feature in these images.

This is how my UIViewController is working :

I have a main UIScrollView that contains many UIScrollView (one per image). Basically in each of these UIScrollView, there is an UIImageView. (I didn't use UICollectionView to allow zoom : I just have many UIScrollView that contain UIImageView, to allow zoom in each image).

This is how it looks :

enter image description here

This is how I did it :

var counter : Int = 0
let scrollViewWidth:CGFloat = scrollView.frame.width
let scrollViewHeight:CGFloat = scrollView.frame.height

// Add images to scrollview
for object in myObjects {
    // Configure the UIImageView
    let imgView = UIImageView(image: object.image.value)
    imgView.frame = CGRect(x:0, y:0, width:scrollViewWidth, height:scrollViewHeight)
    imgView.contentMode = .scaleAspectFit
    imgView.isUserInteractionEnabled = true
    if let rotation = viewModel?.documents?[counter].rotation {
        imgView.transform = CGAffineTransform(rotationAngle: rotation)
    }

    // Configure a UIScrollView for each UIImageView to allow both zooming and paging
    let pageScrollView = UIScrollView(frame: CGRect(x:scrollViewWidth * CGFloat(counter), y:0, width:scrollViewWidth, height:scrollViewHeight))
    pageScrollView.minimumZoomScale = 1.0
    pageScrollView.maximumZoomScale = 2.0
    pageScrollView.contentSize = imgView.bounds.size
    pageScrollView.showsVerticalScrollIndicator = false
    pageScrollView.showsHorizontalScrollIndicator = false
    pageScrollView.addSubview(imgView)
    self.scrollView.addSubview(pageScrollView)
    counter += 1
}

// Set content size for the main UIScrollView
self.scrollView.contentSize = CGSize(width:self.scrollView.frame.width * CGFloat((viewModel?.documents)!.count), height:self.scrollView.frame.height)

Obviously I implemented the viewForZooming method : the method is called, the method returns the right UIImageView, but nothing happens when I pinch to zoom :

/// Zoom in / out for the current UIImageView
public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    // self.scrollView : main UIScrollView
    if scrollView == self.scrollView {
        if let childScrollView = self.scrollView.subviews[currentPageIndex] as? UIScrollView {
            if let currentImageView = childScrollView.subviews[0] as? UIImageView {
                return currentImageView // the UIImageView is well returned
            }
        }
    }
    return nil
}

I don't understand, if anyone have an idea ?

Thanks.

Upvotes: 3

Views: 1561

Answers (2)

AnthonyR
AnthonyR

Reputation: 3545

Solved. In fact as I set the delegate both to my main UIScrollView and the other UIScrollView, the viewForZooming method didn't know what scrollView was used. Instead of testing if the scrollView used in the method was the main UIScrollView (if scrollView == self.scrollView), I have to test if the scrollView was a child of the main UIScrollView.

Like this :

/// Zoom in / out for the current UIImageView
public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    // I removed the test for the main UIScrollView...
    if let childScrollView = self.scrollView.subviews[currentPageIndex] as? UIScrollView {
        if let currentImageView = childScrollView.subviews[0] as? UIImageView {
            // ...And now I test if the scrollView is the child 
            if scrollView == childScrollView { 
                return currentImageView
            }
        }
    }
    return nil
}

Now it works !

Upvotes: 0

Andrew Romanov
Andrew Romanov

Reputation: 5066

Set delegate to every pageScrollView (not for self.scrollView). In the viewForZooming, return appropriate subview. Example (pseudocode):

public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    // self.scrollView : main UIScrollView
    if <scrollView ONE_OF self.pageScrollViews> {
        return self.getContentViewForPageScrollView(scrollView);
    }
}
return nil

Here you can find example project with minimum of the layout features.

}

Upvotes: 1

Related Questions