我有一个UIViewController
,我通过将UIImageView
嵌入UIScrollView
内来制作了zoomableImageView。
class ZoomableImageView: UIScrollView {
// public so that delegate can access
public let imageView: UIImageView = {
let _imageView = UIImageView()
_imageView.translatesAutoresizingMaskIntoConstraints = false
return _imageView
} ()
// this method will be called multiple times to display different images
public func setImage(image: UIImage) {
imageView.image = image
imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
self.contentSize = image.size
// gw: not working here, too early
setZoomScale()
}
func setZoomScale() {
let imageViewSize = imageView.bounds.size
let scrollViewSize = self.bounds.size
let widthScale = scrollViewSize.width / imageViewSize.width
let heightScale = scrollViewSize.height / imageViewSize.height
print("gw: imageViewSize: \(imageViewSize), scrollViewSize: \(scrollViewSize)")
self.minimumZoomScale = min(widthScale, heightScale)
self.maximumZoomScale = 1.2 // allow maxmum 120% of original image size
// set initial zoom to fit the longer side (longer side ==> smaller scale)
zoomScale = minimumZoomScale
}
}
每次更改图像视图的UIImage
时,我都想等待UIImageView
的装订尺寸稳定下来,然后才能使用它来计算放大的比例因子UIScrollView
。
问题:放置setZoomScale()
的合适位置是什么?我在退出setImage
方法之前将其正确放置,但是imageView.bounds.size
在我的打印语句中不正确。请注意,每次图像更改时都需要触发它,而不仅仅是初始视图加载阶段。
我还尝试将setZoomScale
放入ViewController的viewWillLayoutSubviews
中,但这里还有一个问题:viewWillLayoutSubviews
在视图初始化阶段仅被调用一次吗?我可以使用setNeedsLayout
强制触发它吗? (我尝试过,但没有重新触发viewWillLayoutSubviews)
答案 0 :(得分:1)
由于任何改变UI元素调度操作的主要调度队列,你可以把你的代码DispathQueue.main.async{}
,以确保它运行的UI变化完成后。
public func setImage(image: UIImage) {
imageView.image = image
imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
self.contentSize = image.size
// gw: not working here, too early
DispatchQueue.main.async{
self.setZoomScale()
}
}