UIScrollView上的“ CALayer位置包含NaN:[nan nan]”

时间:2018-12-10 12:58:23

标签: ios swift uiscrollview uiimageview autolayout

我正在开发一个屏幕,其中UIImageView内只有一个UIScrollViewUIScrollView使用户可以固定和缩放图像。我从下面的帖子中得到了帮助。它使用情节提要和AutoLayout。基本上,它有8个约束,分别是顶部,底部,前导和尾随(scrollview到superview,imageView到scrollView)。示例帖子在情节提要板内部设置了图像,因此不需要指定任何特定的高度或宽度。

https://www.raywenderlich.com/560-uiscrollview-tutorial-getting-started

我的问题是,当我使用相同的代码但以编程方式进行所有操作时,我可以看到图像(已额外缩放),并且可以用一根手指滚动,但是当我想要捏住它时(缩小,放大)我

  

“ CALayer职位包含NaN:[nan nan]”

错误。我认为这是因为scrollview没有设置contentSize或contentOffset,但是无论我是否设置了该属性,我都会遇到相同的错误。

 override func viewDidLoad() {

    self.scrollView.delegate = self
    self.scrollView.translatesAutoresizingMaskIntoConstraints = false
    self.imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.image = photo
    imageView.contentMode = .scaleAspectFit
    scrollView.addSubview(imageView)
    self.view.addSubview(scrollView)
    self.imageView.setContentHuggingPriority(UILayoutPriority.init(251), for: NSLayoutConstraint.Axis.vertical)
    self.imageView.setContentHuggingPriority(UILayoutPriority.init(251), for: NSLayoutConstraint.Axis.horizontal)

    scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
    scrollView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

    imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: self.scrollView.topAnchor, constant: 0)
    imageViewTopConstraint.isActive = true

    imageViewBottomConstraint = imageView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor, constant: 0)
    imageViewBottomConstraint.isActive = true

    imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor, constant: 0)
    imageViewLeadingConstraint.isActive = true

    imageViewTrailingConstraint = imageView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor, constant: 0)
    imageViewTrailingConstraint.isActive = true

    scrollView.contentSize = imageView.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
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    updateMinZoomScaleForSize(view.bounds.size)
}

fileprivate func updateConstraintsForSize(_ size: CGSize) {

    let yOffset = max(0, (size.height - imageView.frame.height) / 2)
    imageViewTopConstraint.constant = yOffset
    imageViewBottomConstraint.constant = yOffset

    let xOffset = max(0, (size.width - imageView.frame.width) / 2)
    imageViewLeadingConstraint.constant = xOffset
    imageViewTrailingConstraint.constant = xOffset

    view.layoutIfNeeded()
}

}

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

func scrollViewDidZoom(_ scrollView: UIScrollView) {
    updateConstraintsForSize(view.bounds.size)
}

}

1 个答案:

答案 0 :(得分:0)

我通过将updateMinZoomScaleForSize(view.bounds.size)函数从ViewDidLayoutSubViews()移动到ViewDidLoad()并在调用ZoomScale函数之前调用self.view.layoutIfNeeded()使其工作。因此,我的最终作品ViewDidLoad()

    override func viewDidLoad() {
    super.viewDidLoad()
    self.scrollView.delegate = self
    self.scrollView.translatesAutoresizingMaskIntoConstraints = false
    self.imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.image = photo
    imageView.contentMode = .scaleAspectFit
    imageView.clipsToBounds = true
    scrollView.addSubview(imageView)
    //scrollView.contentSize = CGSize(width: imageView.image!.size.width, height: imageView.image!.size.height)
    self.view.addSubview(scrollView)
    self.imageView.setContentHuggingPriority(UILayoutPriority.init(251), for: NSLayoutConstraint.Axis.vertical)
   self.imageView.setContentHuggingPriority(UILayoutPriority.init(251), for: NSLayoutConstraint.Axis.horizontal)

    scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
    scrollView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

    imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: self.scrollView.topAnchor, constant: 0)
    imageViewTopConstraint.isActive = true

    imageViewBottomConstraint = imageView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor, constant: 0)
    imageViewBottomConstraint.isActive = true

    imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor, constant: 0)
    imageViewLeadingConstraint.isActive = true

    imageViewTrailingConstraint = imageView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor, constant: 0)
    imageViewTrailingConstraint.isActive = true


    self.view.layoutIfNeeded()
    updateMinZoomScaleForSize(view.bounds.size)

}