在初始viewDidLoad周期之后,如何等待子视图布局稳定下来?

时间:2019-01-31 01:35:24

标签: ios swift

我有一个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)

1 个答案:

答案 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()
    }
}