【问题标题】:UIScrollView crashing when trying to scroll left or right off screen尝试向左或向右滚动屏幕时 UIScrollView 崩溃
【发布时间】:2020-01-19 23:35:13
【问题描述】:

我的层次结构是 scrollView > UiView(命名为 contentView) > imageView

我将 sv 固定到父视图的 l,r,t,b,contentView 固定到 sv 的 t,b 和父视图的宽度,imageView 固定到 l contentView 的,r,t,b。

使用 iPad 时,图像会占据整个屏幕。当我向上和向下滑动时,scrollView 滚动没有问题。当我向左或向右滑动时,我会崩溃:

* 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'* -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: 尝试插入 nil 对象 对象[0]'

为什么我可以毫无问题地上下滚动,但在尝试向左或向右滚动时会崩溃?

MyVC: UIViewController, UIScrollViewDelegate {

lazy var scrollView: UIScrollView = {
    let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.backgroundColor = .white
    return scrollView
}()

lazy var containerView: UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

lazy var imageView: UIImageView = {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
}()

override func viewDidLoad() {
    super.viewDidLoad()


    scrollView.delegate = self
    scrollView.minimumZoomScale = 1.0
    scrollView.maximumZoomScale = 6.0

    setAnchors()
}

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

func setAnchors() {

    view.addSubview(scrollView)
    scrollView.addSubview(containerView)
    containerView.addSubview(imageView)

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

    containerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

    imageView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
    imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
    imageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
    imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true

    scrollView.contentSize = CGSize(width: scrollView.contentSize.width, height: view.frame.height)
}

}

更新:

我尝试使用这些约束,但它仍然崩溃:

containerView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true

【问题讨论】:

  • 因为水平内容视图约束是错误的。您正在错误地执行整个内容视图和内容大小的事情。
  • containerView 缺少约束leadingAnchor
  • @Nullable 我更新了答案以显示我尝试设置 containerView 的前导和尾随,但它仍然崩溃。不过谢谢:)
  • 那些还是错的。您必须在所有四个侧面都固定到滚动视图的内容布局指南。没有宽度限制。不要尝试手动设置内容大小。只需使容器视图水平约束与正确的垂直约束完全相同。
  • 我认为 scrollView 从其内容的 w/h 中获取 w/h。如果不是手动设置,那怎么办?

标签: ios swift uiview uiscrollview


【解决方案1】:

我更新了你的一些代码

我给imageView添加了一张本地图片00

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        scrollView.delegate = self
        scrollView.minimumZoomScale = 1.0
        scrollView.maximumZoomScale = 6.0

        imageView.image = UIImage.init(named: "00")
        setAnchors()
    }

    lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.backgroundColor = .white
        return scrollView
    }()

    lazy var containerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFill
        return imageView
    }()

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

    func setAnchors() {

        view.addSubview(scrollView)
        scrollView.addSubview(containerView)
        containerView.addSubview(imageView)

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

        containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        containerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

        imageView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        imageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true

        scrollView.contentSize = CGSize(width: view.bounds.size.width, height: view.frame.height)
    }

这是 iPad 模拟器的 gif。

我已经用 iPhone 测试过它,它可以工作。希望对你有帮助

【讨论】:

  • 我的代码在 iPhone 上运行良好,在 iPad 上它崩溃了。在那里测试你的代码,看看会发生什么。
  • 对不起,我只有一个iPad模拟器,模拟器测试正常。
  • 我试过了,它在这里崩溃了 (imageView.image?.size.width)! 它是 nil
  • 需要在setAnchors()之前设置imageView.image
  • 它有效,我将接受答案,但它引起了另一个问题 - 图像被拉伸到屏幕之外。当我滚动时,它滚动受限并且滚动无法正常工作。我将 imageView 更改为 .scaleAspectFit
猜你喜欢
  • 1970-01-01
  • 2013-05-14
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多