Search code examples
iosswiftuiscrollviewuiimageviewuiimage

How to make a UIImage Scrollable inside a UIScrollView?


I currently have a ScrollView and inside the ScrollView i have a UIImageView.

I get different image sizes from my server and most images are larger than the bounds of my screen.

I would like to scroll through the image if it is bigger than my screen.

Something like this....

enter link description here

This is what i have tried so far.

let image = UIImage(named: "myImg")
let heightInPoints = image?.size.height
let heightInPixels = heightInPoints ?? 0 * image!.scale
let widthInPoints = image?.size.width
let widthInPixels = widthInPoints ?? 0 * image!.scale

self.imageView.frame = CGRect(x: 0, y: 0, width: widthInPixels, height: heightInPixels) //= image
self.imageView.image = image

scrollView.contentSize = CGSize(width: imageView.frame.width, height: imageView.frame.height)

But it doesn't seem to work. Either it only scrolls vertically or horizontally or it never scrolls.

What am I doing wrong. Or is there a better approach to get this effect ?


Solution

  • Solution 1. Updating Frames

    Firstly, make sure the views hierarchy is correctly setup (the imageView is added to the scrollView):

    scrollView.addSubview(imageView)
    

    Then I'd suggest rewriting this code as something like:

    let image = UIImage(named: "myImg")
    imageView.image = image                        // setup image to imageView
    imageView.frame.size = image?.size ?? .zero    // setup image size or zero to imageView
    scrollView.contentSize = image.size ?? .zero   // setup image size or zero as a content size
    

    Solution 2. Using constraints

    There is also another solution using constraints instead of manually setting up the sizes. This takes a bit more code but doesn't require sizes recomputing when you change the image.

    scrollView.addSubview(imageView)                            // Setup the views hierarchy
    imageView.translatesAutoresizingMaskIntoConstraints = false // Make sure constraints won't interfere with autoresizing mask
    NSLayoutConstraint.activate(
        [
            imageView.leftAnchor.constraint(equalTo: scrollView.leftAnchor),    // attaching to the left
            imageView.topAnchor.constraint(equalTo: scrollView.topAnchor),      // attaching to the top
            imageView.rightAnchor.constraint(equalTo: scrollView.rightAnchor),  // attaching to the right
            imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor) // attaching to the bottom
        ]
    )
    

    Then we replace existing image with a new one like this:

    imageView.image = UIImage(named: "myImg") 
    

    Both approaches work for me in Playground. So, if these still won't work for you, please share more information about how you set up the hierarchy and additional parameters of the scroll view.