我将UIImageView
嵌入UIContentView
内以使其可缩放和平移(reference。问题是图像未正确居中。看起来整个图像内容从左上角移出:
打印内容的偏移量接近零时:content offset is: (0.0, -20.0)
这是我的实现方式:
import UIKit
class ZoomableImageView: UIScrollView {
private struct Constants {
static let minimumZoomScale: CGFloat = 0.5;
static let maximumZoomScale: CGFloat = 6.0;
}
// public so that delegate can access
public let imageView = UIImageView()
// gw: must be called to complete a setting
public func setImage(image: UIImage) {
imageView.image = image
imageView.bounds = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
self.contentSize = image.size
let scaleFitZoomScale: CGFloat = min(
self.frame.width / image.size.width ,
self.frame.height / image.size.height
)
// reset scale and offset on each resetting of image
self.zoomScale = scaleFitZoomScale
}
// MARK - constructor
init() {
// gw: there is no super.init(), you have to use this constructor as hack
super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) // gw: relies on autolayout constraint later
minimumZoomScale = Constants.minimumZoomScale
maximumZoomScale = Constants.maximumZoomScale
addSubview(imageView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
ViewController:
class ViewController: UIViewController, UIScrollViewDelegate {
let zoomableImageView = ZoomableImageView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(zoomableImageView)
zoomableImageView.delegate = self
}
override func viewDidLayoutSubviews() {
zoomableImageView.frame = view.frame
let image = UIImage(imageLiteralResourceName: "kelly")
zoomableImageView.setImage(image: image)
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
// print("scale factor is: \(scrollView.zoomScale)")
return zoomableImageView.imageView
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
print("scale factor is: \(scrollView.zoomScale)")
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("content offset is: \(scrollView.contentOffset)")
}
}
但是,如果我不将UIImageView
和UIScrollView
包装在自定义类下,则图像的居中效果会很好:
class ViewController: UIViewController, UIScrollViewDelegate {
let imageView: UIImageView = {
let image = UIImage(imageLiteralResourceName: "kelly")
let imageView = UIImageView(image: image)
imageView.bounds = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
return imageView
} ()
let scrollView: UIScrollView = {
let scrollView = UIScrollView()
return scrollView
} ()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.addSubview(scrollView)
scrollView.addSubview(imageView)
scrollView.delegate = self
self.scrollView.minimumZoomScale = 0.5;
self.scrollView.maximumZoomScale = 6.0;
}
override func viewDidLayoutSubviews() {
scrollView.frame = view.frame
if let size = imageView.image?.size {
scrollView.contentSize = size
}
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
}
我在第一个实现中错过了什么吗?
答案 0 :(得分:2)
在您的ZoomableImageView
类中,您正在设置 bounds
何时应为 frame
因此更改:
imageView.bounds = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
到
imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)