«Позиция CALayer содержит NaN: [nan nan]» в UIScrollView - PullRequest
0 голосов
/ 10 декабря 2018

Я разрабатываю экран, который имеет только один UIImageView внутри UIScrollView.UIScrollView позволяет пользователям закреплять и масштабировать изображение.Я получил помощь от поста ниже.Он использует раскадровку и AutoLayout.По сути, он имеет 8 ограничений: верхний, нижний, ведущий и конечный (от scrollview до superview и от imageView до scrollView).Пример поста устанавливает изображение внутри раскадровки так, что ему не нужно указывать какую-либо конкретную высоту или ширину.

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

Моя проблема в том, что когда я использую тот же код, но все делаю программно, Я могу видеть изображение (с дополнительным увеличением) и прокручивать одним пальцем, но когда я хочу ущипнуть его (уменьшить, увеличить), я получил

'CALayer position содержит 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 голосов
/ 10 декабря 2018

Я заставляю его работать, перемещая функцию updateMinZoomScaleForSize(view.bounds.size) с ViewDidLayoutSubViews() на ViewDidLoad() и вызывая self.view.layoutIfNeeded() перед вызовом функции ZoomScale.Поэтому мой окончательный и рабочий 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)

}
...