scale image to size with aspectFit - ios

I am building a app where you can drag images inside a view. Currently it look like this:
As you can see I marked the background color from the image view in green. The image view has contentMode aspectFit and it is 40 pixels smaller than the black view behind it.
I want the that the image is the full length and width of the image view. The contentMode should be aspectFit, that nothing is cut away from the image. Is it possible to resize the image, that it has 20 pixels or a bit more space from the view?

#adri567 You should use UIViewContentModeScaleToFill property like
imageView.contentMode = .scaleToFill
Try with this!

If you want to keep the image at the same size, but don't want to stretched it. your solution is something else.
Display your image as .aspectFit as in the question
the green view that you display replace it with the same image in .aspectFill but blur it as much as it looks good.

Simple math can solve this.
for shortcuts: H -> height , W -> Width
We know that general formula for this is: h1 / w1 = h2 / w2
Hscreen / Wscreen = Himage / Wimage
so we know screen width, image height and image width.
we can get screen width as -> view.frame.width
also we can get image size as -> image.size.width and image.size.height
Hscreen = (Himage) * (WScreen) / Wimage
..
you can use Hscreen to imageViews height anchor.

One approach...
embed a UIImageView in a (green) UIView
constrain the imageView on all 4 sides + 20-pts "padding"
constrain the width of the greenView (or its leading and trailing)
constrain the Y position of the greenView (top or centerY)
constrain the height of the imageView with a multiplier based on the image width and height
Here is a simple example:
class ViewController: UIViewController {
let imgView: UIImageView = {
let v = UIImageView()
v.contentMode = .scaleToFill
return v
}()
let greenView: UIView = {
let v = UIView()
v.backgroundColor = .green
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
// replace with your image name
guard let img = UIImage(named: "bkg640x360") else {
fatalError("Could not load image!")
}
view.backgroundColor = .black
// set the imgView's image
imgView.image = img
// use auto-layout constraints
imgView.translatesAutoresizingMaskIntoConstraints = false
greenView.translatesAutoresizingMaskIntoConstraints = false
// add imgView to greenview
greenView.addSubview(imgView)
// add greenView to self.view
view.addSubview(greenView)
// we want to respect safe-area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain greenView leading and trailing to view (safeArea)
greenView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
greenView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
// constrain greenView centerY to view centerY
greenView.centerYAnchor.constraint(equalTo: g.centerYAnchor, constant: 0.0),
// constrain imgView to all 4 sides of greenView with 20-pts "padding"
imgView.topAnchor.constraint(equalTo: greenView.topAnchor, constant: 20.0),
imgView.bottomAnchor.constraint(equalTo: greenView.bottomAnchor, constant: -20.0),
imgView.leadingAnchor.constraint(equalTo: greenView.leadingAnchor, constant: 20.0),
imgView.trailingAnchor.constraint(equalTo: greenView.trailingAnchor, constant: -20.0),
// constrain imgView proportional height equal to image height / width
imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: img.size.height / img.size.width),
])
}
}
The result, using a 640 x 360 image:
and using a 512 x 512 (square) image:
These are my source images:

Related

Understanding layout anchors in Swift

So, I have this ViewController where I render an image inside a subview.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
let childView = UIView()
childView.backgroundColor = .red
let imageView = UIImageView(image: UIImage(systemName: "tray"))
imageView.contentMode = .scaleAspectFill
childView.addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.heightAnchor.constraint(equalToConstant: 100.0)
])
view.addSubview(childView)
childView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
childView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor)
])
}
}
As you can see for some reason, the image moves to the left of screen. What is the cause of that?
One more thing I noticed is the subview should have a background color of red as specified, but somehow it's transparent. Why is that?
I expect the result to be something like,
You are adding way too few constraints. The horizontal position and size of the childView are not constrained at all, so the size just defaults to (0, 0), making the view not visible at all, which is why you don't see the red background.
First, let's constrain the horizontal position. This seems to be what you intended:
NSLayoutConstraint.activate([
// wouldn't it be better to use safeAreaLayoutGuide?
childView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
childView.leftAnchor.constraint(equalTo: view.layoutMarginsGuide.leftAnchor)
])
Then, the size of the childView should be the same as the imageView, so you should activate these constraints too:
imageView.leftAnchor.constraint(equalTo: childView.leftAnchor),
imageView.rightAnchor.constraint(equalTo: childView.rightAnchor),
imageView.topAnchor.constraint(equalTo: childView.topAnchor),
imageView.bottomAnchor.constraint(equalTo: childView.bottomAnchor),
There is one more thing though - the size of the image view at this point is not what you expect. The image view has a height of 100, but its width is still 24, which is the intrinsic size of the "tray" image. scaleAspectFill does scale the image to the size you want, but the views' widths stay at 24, and since the scaling is done from the centre of the view, the scaled up image appears to be "off centred".
I think that in general, you'll just have to manually calculate the width you want:
let width = 100 * image.size.width / image.size.height
and constrain both width and height:
imageView.heightAnchor.constraint(equalToConstant: 100.0),
imageView.widthAnchor.constraint(equalToConstant: width),
However, with SF symbols, you can get a bigger image simply by:
let image = UIImage(systemName: "tray", withConfiguration: UIImage.SymbolConfiguration(pointSize: 100))
You don't need any height or width constraints on the image view.

UIImageView cuts inside UIScrollView

I'm trying to create UIScrollView With UIStackView that contains multiple UIImageView with this code:
let stackView = UIStackView(frame: .zero)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.backgroundColor = .green
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
self.view.addSubview(scrollView)
scrollView.anchor(top: textSV.bottomAnchor, leading: self.view.safeAreaLayoutGuide.leadingAnchor, bottom: anotherView?.topAnchor, trailing: self.view.safeAreaLayoutGuide.trailingAnchor)
scrollView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
scrollView.contentInsetAdjustmentBehavior = .never
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.distribution = .equalSpacing
stackView.spacing = 0
scrollView.addSubview(stackView)
stackView.fillSuperview()
for _ in 1...8 {
let pageView = UIImageView(image: UIImage(named: "iphone12mockup"))
pageView.clipsToBounds = true
pageView.contentMode = .scaleAspectFit
pageView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(pageView)
pageView.anchor(top: stackView.topAnchor, leading: nil, bottom: stackView.bottomAnchor, trailing: nil)
}
The problem is that the UIImageView does not resize to scaleAspectFit and it looks like this(Can't see full image):
EDIT
let img = UIImage(named: "iphone12mockup")
let width = img?.size.width
let pageView = UIImageView(image: img)
pageView.clipsToBounds = true
pageView.contentMode = .scaleAspectFit
pageView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(pageView)
pageView.anchor(top: stackView.topAnchor, leading: nil, bottom: stackView.bottomAnchor, trailing: nil)
pageView.widthAnchor.constraint(equalToConstant: width!).isActive = true
You want to make use of the scroll view's Content and Frame Layout Guides...
constrain all 4 sides of the stack view to the scroll view's Content Layout Guide
constrain the stack view's Height to the scroll view's Frame Layout Guide
for each image view you add to the stack view:
constrain the image view's Width to the scroll view's Frame Layout Guide
Here is a complete example:
class ViewController: UIViewController, UIScrollViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// just trying to include what you've shown
let textSV = UILabel()
textSV.backgroundColor = .yellow
textSV.text = "textSV"
textSV.textAlignment = .center
let anotherView = UILabel()
anotherView.backgroundColor = .cyan
anotherView.text = "anotherView"
anotherView.textAlignment = .center
[textSV, anotherView].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
// respect safe area
let safeG = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
textSV.topAnchor.constraint(equalTo: safeG.topAnchor),
textSV.leadingAnchor.constraint(equalTo: safeG.leadingAnchor),
textSV.trailingAnchor.constraint(equalTo: safeG.trailingAnchor),
textSV.heightAnchor.constraint(equalToConstant: 60.0),
anotherView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor),
anotherView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor),
anotherView.bottomAnchor.constraint(equalTo: safeG.bottomAnchor),
anotherView.heightAnchor.constraint(equalToConstant: 60.0),
])
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.backgroundColor = .green
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
view.addSubview(scrollView)
// use a stack view to hold and arrange the scrollView's subviews
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
// add the stackView to the scrollView
scrollView.addSubview(stackView)
// use scrollView's Content Layout Guide to define scrollable content
let layoutG = scrollView.contentLayoutGuide
// use scrollView's Frame Layout Guide to define content height (since you want horizontal scrolling)
let frameG = scrollView.frameLayoutGuide
NSLayoutConstraint.activate([
// constrain scrollView Top to textSV Bottom
scrollView.topAnchor.constraint(equalTo: textSV.bottomAnchor),
// constrain scrollView Leading/Trailing to safe area
scrollView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor),
// constrain scrollView Bottom to anotherView Top
scrollView.bottomAnchor.constraint(equalTo: anotherView.topAnchor),
// constrain all 4 sides of the stackView to scrollView's Content Layout Guide
stackView.topAnchor.constraint(equalTo: layoutG.topAnchor),
stackView.bottomAnchor.constraint(equalTo: layoutG.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: layoutG.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: layoutG.trailingAnchor),
// constrain stackView's height to scrollView's Frame Layout Guide height
stackView.heightAnchor.constraint(equalTo: frameG.heightAnchor),
])
// add imageViews to the stack view
for _ in 1...8 {
let pageView = UIImageView(image: UIImage(named: "iphone12mockup"))
//let pageView = UIImageView(image: UIImage(named: "sample"))
// set image view background color so you can
// see its frame (since the image will be aspect-fit scaled)
pageView.backgroundColor = .systemYellow
pageView.contentMode = .scaleAspectFit
// add it to the stack view
stackView.addArrangedSubview(pageView)
// constrain its Width to scrollView's Frame Layout Guide Width
pageView.widthAnchor.constraint(equalTo: frameG.widthAnchor).isActive = true
}
}
}
It will look like this on startup (on an iPhone 8):
and after scrolling a little to the right:
Note that since you want the image view set to Aspect Fit, I gave the "pageView" image views a background color of .systemYellow so you can see that the imageView frame fills the scroll view frame width and height.
Edit -- if you want the images to be proportional to their height, without "empty space on the sides," you need to set the image view width constraint proportional to its height, based on the image size.
Replace the "add image views" loop with this:
// add imageViews to the stack view
for _ in 1...8 {
guard let img = UIImage(named: "iphone12mockup") else {
fatalError("Could not load image!")
}
let pageView = UIImageView()
pageView.image = img
pageView.contentMode = .scaleToFill
// add it to the stack view
stackView.addArrangedSubview(pageView)
// constrain its Width proportional to the image height
pageView.widthAnchor.constraint(equalTo: pageView.heightAnchor, multiplier: img.size.width / img.size.height).isActive = true
}
and the output will be:
and after scrolling a little to the right:

Vertically rotated UIPageControl taking too much space

I used CGAffineTransform to rotate a horizontal UIPageControl vertical. But when I added it besides my collection view it's taking too much width. And when I add a width anchor on it, the UIPageControl disappears.
noticesPagingIndicator = UIPageControl()
let angle = CGFloat.pi/2
noticesPagingIndicator.transform = CGAffineTransform(rotationAngle: angle)
NSLayoutConstraint.activate([
// noticesPagingIndicator.widthAnchor.constraint(equalToConstant: 30),
noticesPagingIndicator.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
noticesPagingIndicator.centerYAnchor.constraint(equalTo: noticesCollectionView.centerYAnchor),
noticesCollectionView.leadingAnchor.constraint(equalTo: noticesPagingIndicator.trailingAnchor),
noticesCollectionView.topAnchor.constraint(equalTo: noticeStackView.bottomAnchor, constant: 8),
noticesCollectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
noticesCollectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
])
When I look at the UIView hierarchy, I see a lot of padding along the UIPageControl
With the width anchor enabled:
Get to know the Debug View Hierarchy tool. It can help you figure out most layout issues.
When you transform a view, that doesn't change its bounds and thus doesn't change its constraint relationships to other UI elements.
With this code (8 pages, so 8 dots):
class ViewController: UIViewController {
let pgc = UIPageControl()
let greenLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemYellow
pgc.translatesAutoresizingMaskIntoConstraints = false
greenLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pgc)
view.addSubview(greenLabel)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// page control Leading to safe area Leading + 20, centerY
pgc.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
pgc.centerYAnchor.constraint(equalTo: g.centerYAnchor, constant: 0.0),
// constrain greenLabel Leading to page control trailing + 8 and centerY, safe area trailing -8
greenLabel.leadingAnchor.constraint(equalTo: pgc.trailingAnchor, constant: 8.0),
greenLabel.centerYAnchor.constraint(equalTo: pgc.centerYAnchor),
greenLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
])
// rotate the page control
let angle = CGFloat.pi/2
pgc.transform = CGAffineTransform(rotationAngle: angle)
pgc.backgroundColor = .systemBlue
greenLabel.backgroundColor = .green
pgc.numberOfPages = 8
greenLabel.numberOfLines = 0
greenLabel.text = "UIPageControl indicates the number of open pages in an application by displaying a dot for each open page. The dot that corresponds to the currently viewed page is highlighted. UIPageControl supports navigation by sending the delegate an event when a user taps to the right or to the left of the currently highlighted dot."
}
}
You get this output:
As you've seen, the Green Label Leading constraint to the page control Trailing Anchor shows the page control width matches what it would be without the rotation.
If you inspect the views with Debug View Hierarchy, you'll see the page control looks like this:
The frame is w: 27.5 h: 217 but the bounds is w: 217 h: 27.5.
To fix this, you need to embed the page control in a "holder" view, constrain the holder view's Height to the page control's Width and Width to Height. Then constrain your other elements to that "holder" view:
class ViewController: UIViewController {
let pgcHolder = UIView()
let pgc = UIPageControl()
let greenLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemYellow
pgcHolder.translatesAutoresizingMaskIntoConstraints = false
pgc.translatesAutoresizingMaskIntoConstraints = false
greenLabel.translatesAutoresizingMaskIntoConstraints = false
pgcHolder.addSubview(pgc)
view.addSubview(pgcHolder)
view.addSubview(greenLabel)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// center page control in its "holder" view
pgc.centerXAnchor.constraint(equalTo: pgcHolder.centerXAnchor),
pgc.centerYAnchor.constraint(equalTo: pgcHolder.centerYAnchor),
// constrain holder view leading to view + 20, centerY
pgcHolder.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
pgcHolder.centerYAnchor.constraint(equalTo: g.centerYAnchor, constant: 0.0),
// constrain holder view WIDTH to page control HEIGHT
pgcHolder.widthAnchor.constraint(equalTo: pgc.heightAnchor),
// constrain holder view HEIGHT to page control WIDTH
pgcHolder.heightAnchor.constraint(equalTo: pgc.widthAnchor),
// constrain greenLabel Leading to holder view trailing + 8 and centerY, safe area trailing -8
greenLabel.leadingAnchor.constraint(equalTo: pgcHolder.trailingAnchor, constant: 8.0),
greenLabel.centerYAnchor.constraint(equalTo: pgcHolder.centerYAnchor),
greenLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
])
let angle = CGFloat.pi/2
pgc.transform = CGAffineTransform(rotationAngle: angle)
pgcHolder.backgroundColor = .systemRed
pgc.backgroundColor = .systemBlue
greenLabel.backgroundColor = .green
pgc.numberOfPages = 8
greenLabel.numberOfLines = 0
greenLabel.text = "UIPageControl indicates the number of open pages in an application by displaying a dot for each open page. The dot that corresponds to the currently viewed page is highlighted. UIPageControl supports navigation by sending the delegate an event when a user taps to the right or to the left of the currently highlighted dot."
}
}
Now we have our desired output:
#DonMag Answer with storyboard
Step 1 :
In View Controller, Drag UIVIew --> Name it (holderView)
Step 2 :
Drag Page Control in the holderView
Step 4:
Select the holder View - add Center Y Constraint , Trailing Constraint with Super View
Step 5:
Select the page Control View - add Center X , Center Y constraint
Step 6 :
From the View List on left panel , select both parent view and page control view , add Equal With and Equal Height constraint
Step 7:
Now select the Equal Width constraint and from left panel (properties of constraint) update superView Width to SuperView Height ,
Same for Height Constraint
Your Constraint should look like this

Autolayout programmatic aspect ratio setting

I am trying to add a subview to view and define autolayout constraints, including aspect ratio. But aspect ratio that I see at runtime is not what I defined in constraints. What am I doing wrong? As you can see in code, background view height should be 0.5 of background view width, but that's not the case here in the screenshot. Here is my code:
class ViewController: UIViewController {
private var backgroundView:UIView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.backgroundColor = UIColor.orange
backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
backgroundView?.backgroundColor = UIColor.black.withAlphaComponent(1.0)
backgroundView?.layer.borderColor = UIColor.white.cgColor
backgroundView?.layer.borderWidth = 1.5
backgroundView?.layer.cornerRadius = 4
backgroundView?.clipsToBounds = true
backgroundView?.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(backgroundView!)
backgroundView?.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true
backgroundView?.heightAnchor.constraint(equalTo: backgroundView!.widthAnchor, multiplier: 0.5).isActive = true
backgroundView?.centerXAnchor.constraint(equalTo: view!.centerXAnchor, constant: 0).isActive = true
backgroundView?.topAnchor.constraint(equalTo: view!.topAnchor, constant: 4).isActive = true
}
}
Here is the screenshot:
"background view height should be 0.5 of background view width"
Your screenshot size is 1334 x 750
Your backgroundView - including the border - is 1334 x 667
1334 * 0.5 == 667
So, you are getting exactly what you are asking for.
Try to change height constraint to set:
backgroundView?.heightAnchor.constraint(equalTo: view!.heightAnchor, multiplier: 0.5).isActive = true
NB: You are getting the exact result which you are looking for. It has the height that's half of its width. There is nothing wrong with the screenshot.

Center UIImageView within a UIScrollView with a larger contentSize

I have a full screen scrollView, to which I add an imageView as subview. I want the imageView to be centered and scaled filling the scrollView's size (that is the screen size) at the beginning, but then to allow the user to scroll the image in both directions (vertical and horizontal) with equal offsets at left, right, top and bottom.
I mean: I've set the scroll view's contentSize to be CGSize(width: screenWidth + 200, height: screenHeight + 200), and if I run the app, I see that I am able to scroll those 200 pts of offset only to the right and to the bottom of the image. I'd like the image to be centered in the content size, and to be able to scroll it horizontally to both to the left and to the right with offset 100 pts each side (similar thing with top and bottom when scrolling vertically).
How could I achieve this?
Note: I'm setting all the UI in code, I'm not using storyboards nor xib files
You may find it easier / more intuitive to use constraints and auto-layout rather than screenWidth and screenHeight:
//
// CenteredScrollViewController.swift
// SW4Temp
//
// Created by Don Mag on 4/18/18.
//
import UIKit
class CenteredScrollViewController: UIViewController {
let theScrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = UIColor.green
return v
}()
let theImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = UIColor.blue
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
// add the scrollView to the main view
view.addSubview(theScrollView)
// add the imageView to the scrollView
theScrollView.addSubview(theImageView)
// pin the scrollView to all four sides
theScrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0).isActive = true
theScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0).isActive = true
theScrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
theScrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true
// constrain the imageView's width and height to the scrollView's width and height
theImageView.widthAnchor.constraint(equalTo: theScrollView.widthAnchor, multiplier: 1.0).isActive = true
theImageView.heightAnchor.constraint(equalTo: theScrollView.heightAnchor, multiplier: 1.0).isActive = true
// set the imageView's top / bottom / leading / trailing anchors
// this *also* determines the scrollView's contentSize (scrollable area)
// with 100-pt padding on each side
theImageView.topAnchor.constraint(equalTo: theScrollView.topAnchor, constant: 100.0).isActive = true
theImageView.bottomAnchor.constraint(equalTo: theScrollView.bottomAnchor, constant: -100.0).isActive = true
theImageView.leadingAnchor.constraint(equalTo: theScrollView.leadingAnchor, constant: 100.0).isActive = true
theImageView.trailingAnchor.constraint(equalTo: theScrollView.trailingAnchor, constant: -100.0).isActive = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// set the scrollView's contentOffset (to center the imageView)
theScrollView.contentOffset = CGPoint(x: 100, y: 100)
}
}
You can move only down and right because your current content offset is 0,0 so top left - thus you can move down 200 and right 200.
What you want is to be scrolled 1/2 of vertical padding and 1/2 of horizontal padding, so in your case you would do scrollView.contentOffset = CGPoint(x: 100, y: 100)
Also for everything to work, UIImageView has to be same size as scrollView's contentSize, so bigger than screen size.
Given the comments what I think you want is the image to fill the screen and then user could scroll outside of bounds of the image, then you just need to make UIImageView's size be size of the screen its x and y coordinates to be same as contentOffset of the scrollView so (100, 100).
Here is the video of the sample app doing this:
https://dzwonsemrish7.cloudfront.net/items/2v361r2p0O2j1D3x3W10/Screen%20Recording%202018-04-19%20at%2002.32%20PM.mov
try this in
Swift 4.* or 5.*
let maxScale = self.imageScrollView.maximumZoomScale
let minScale = self.imageScrollView.minimumZoomScale
if let imageSize = imageView.image?.size{
let topOffset: CGFloat = (boundsSize.height - minScale * imageSize.height ) / 2
let leftOffset: CGFloat = (boundsSize.width - minScale * imageSize.width ) / 2
self.imageScrollView.contentInset = UIEdgeInsets(top: topOffset, left: leftOffset, bottom: 0, right: 0)
}

Resources