代码之家  ›  专栏  ›  技术社区  ›  modeller

如何等待子视图布局在初始视图加载循环后稳定下来?

  •  0
  • modeller  · 技术社区  · 6 年前

    我有一个 UIViewController ,我通过嵌入 UIImageView 里面 UIScrollView .

    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 在图像视图中,我想等待 UIIVIEVIEW 在我可以使用它计算放大比例因子之前,要确定的绑定大小 UISCLVIEW .

    问题 :放在什么地方合适 setZoomScale() ?我把它放在离开之前 setImage 方法,但 imageView.bounds.size 在我的打印声明中不正确。请注意,每次图像更改时都需要触发它,而不仅仅是初始视图加载阶段。

    我也试着把 setZoomScale 在视图控制器中 viewWillLayoutSubviews ,但我这里还有一个附加问题:是 视图将显示在子视图之外 在视图初始化阶段只调用一次?我能用强制触发吗 setNeedsLayout ?(我尝试过,但不重新触发视图将显示在子视图之外)

    1 回复  |  直到 6 年前
        1
  •  1
  •   Ricky Mo    6 年前

    当对UI元素的任何更改将操作分派到主分派队列时,可以将代码放入 DispathQueue.main.async{} 以确保它在用户界面更改完成后运行。

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