I am implementing a UIScrollView in a UIViewController. I center the image which is slightly smaller than the ScrollView in the contentView and add the contentView to the ScrollView. Zooming in works fine but when zooming out (zoomScale < 1) the image is shifted to the upper left corner.
func makeBgView() {
if let bgImage = UIImage(named: "testImage") {
bgView = UIImageView(image: bgImage)
// calculate contentViewSize from imagesize and height
let imgWidth = bgView.image!.size.width
let imgHeight = bgView.image!.size.height
let bgWidth = view.frame.width * 0.96
let ratio = bgWidth/imgWidth
let bgHeight = imgHeight * ratio
let bgSize = CGSize(width: bgWidth, height: bgHeight)
contentView.addSubview(bgView)
contentView.sendSubviewToBack(bgView)
contentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
contentView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor),
contentView.widthAnchor.constraint(equalToConstant: bgSize.width),
contentView.heightAnchor.constraint(equalToConstant: bgSize.height),
])
bgView.pinToEdges(inView: contentView)
scrollView.addSubview(contentView)
}
extension CanvasVC: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return contentView
}
}
extension UIView {
func pinToEdges(constant: CGFloat = 0, inView superview: UIView) {
superview.addSubview(self)
self.translatesAutoresizingMaskIntoConstraints = false
self.topAnchor.constraint(equalTo: superview.topAnchor, constant: constant).isActive = true
self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: constant).isActive = true
self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: constant).isActive = true
self.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: constant).isActive = true
}
}
The green frame is the ScrollView the RedFrame is the contentView (a UIVIew).