ImageView 的边界在 ViewDidLayoutSubviews() 中为零 [重复]

Posted

技术标签:

【中文标题】ImageView 的边界在 ViewDidLayoutSubviews() 中为零 [重复]【英文标题】:Bounds of an ImageView is zero in ViewDidLayoutSubviews() [duplicate] 【发布时间】:2018-01-24 17:57:32 【问题描述】:

我正在关注 UIScrollView 上的 Raywenderlich 教程,该教程可以平移和缩放图像 (https://www.raywenderlich.com/159481/uiscrollview-tutorial-getting-started)。我的代码与他们的代码完全相同,只是我以编程方式创建了视图和布局约束。我的不行。

我发现问题在于我的ImageViewviewDidLayoutSubviews() 中的bounds 值为零。但是,无论我是在 Storyboard 中还是在代码中创建约束,都应该没有区别,对吧?如果是这样,任何解决方法的建议将不胜感激。 viewDidLoad() 中的部分是我自己的代码。

class ComposeController: UIViewController 

    let scrollView = UIScrollView()
    let imageView = UIImageView()
    var imageViewBottomConstraint: NSLayoutConstraint!
    var imageViewLeadingConstraint: NSLayoutConstraint!
    var imageViewTopConstraint: NSLayoutConstraint!
    var imageViewTrailingConstraint: NSLayoutConstraint!

    override func viewDidLoad() 
        super.viewDidLoad()

        imageView.image = MyImage //from Assets
        scrollView.delegate = self       
        view.addSubview(scrollView)
        scrollView.addSubview(imageView)

        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true

        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: scrollView.topAnchor)
        imageViewBottomConstraint = imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
        imageViewLeadingConstraint = imageView.leftAnchor.constraint(equalTo: scrollView.leftAnchor)
        imageViewTrailingConstraint = imageView.rightAnchor.constraint(equalTo: scrollView.rightAnchor)
        imageViewTopConstraint.isActive = true
        imageViewBottomConstraint.isActive = true
        imageViewLeadingConstraint.isActive = true
        imageViewTrailingConstraint.isActive = true

    

    override func viewDidLayoutSubviews() 
        super.viewDidLayoutSubviews()
        updateMinZoomScaleForSize(view.bounds.size)
    

    fileprivate func updateMinZoomScaleForSize(_ size: CGSize) 
        let widthScale = size.width / imageView.bounds.width
        let heightScale = size.height / imageView.bounds.height
        let minScale = min(widthScale, heightScale)

        scrollView.minimumZoomScale = minScale
        scrollView.zoomScale = minScale
    


extension ComposeController: UIScrollViewDelegate 
    func viewForZooming(in scrollView: UIScrollView) -> UIView? 
        return imageView
    

【问题讨论】:

请在此处查看我的答案:***.com/a/44555450/1305067 @paulvs。工作完美,谢谢。性能方面,我是否在viewDidLoad()viewDidLayoutSubviews() 中调用它们是否重要? 我认为你应该在viewDidLoad 中调用它们,因为它在viewDidLayoutSubviews 之前调用。 【参考方案1】:

根据 Apple 的 viewDidLayoutSubviews() 文档:

当视图控制器视图的边界发生变化时,视图会调整其子视图的位置,然后系统调用此方法。但是,调用此方法并不表示视图的子视图的各个布局已被调整。每个子视图负责调整自己的布局。

您可以通过调用使视图布局各个子视图:

self.view.setNeedsLayout()
self.view.layoutIfNeeded()

【讨论】:

这与我在问题的 cmets 中引用的答案完全相同。 是的,你是对的@paulvs。您应该将您的答案作为完整答案发布,因为它比我的更全面。 完美运行,谢谢@creeperspeak。如果在 Storyboard 中设置了约束,我很好奇为什么不需要这样做 @JGuo 如果尝试在viewDidLayoutSubviews 中获得正确的尺寸,您可能仍然会这样做。我从来没有尝试过,tbh。

以上是关于ImageView 的边界在 ViewDidLayoutSubviews() 中为零 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

ImageView selectableItemBackgroundBorderless 不会在视图边界之外呈现

ImageView 调整视图边界不起作用

如何在圆形 imageView android 上添加一个阴影和边界

Android Studio:缩放 ImageView 边界以适应图像

UIScrollView 缩放:将平移限制为 imageView.image 边界

ImageView 的默认缩放类型是啥?