本文介绍了在父容器中滚动时,水平滚动集合视图将上移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在父UIView中创建了一个水平滚动集合视图,并将其添加到我的UIViewController中.但是,当我在其上滚动时,滚动视图会向上移动.

I have created a horizontal scrolling collection view within a parent UIView, which I add in my UIViewController. But the scrolling view shifts up when I scroll on it.

这是初始化容器视图的方式:

This is how the container view is initialized:

 override init(frame: CGRect){
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
        layout.estimatedItemSize = CGSize(width: 100, height: 50)

        countryCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)

        viewTitleLabel = UILabel()
        super.init(frame: frame)
        setupTableView()
        sortedDummyData = dummyData.sorted(by: <)
    }

对我的孩子视图的约束:

Constraints on my child views:

 NSLayoutConstraint.activate([
            viewTitleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
            viewTitleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor),
            viewTitleLabel.heightAnchor.constraint(equalToConstant: 30),
            viewTitleLabel.widthAnchor.constraint(equalToConstant: 90),

            countryCollectionView.leadingAnchor.constraint(equalTo: viewTitleLabel.trailingAnchor, constant: 10),
            countryCollectionView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
            countryCollectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
            countryCollectionView.heightAnchor.constraint(equalToConstant: 50)

 ])

添加到UIViewContoller时对容器视图的约束:

Constraints on container view when adding to UIViewContoller:

 countryCountView.translatesAutoresizingMaskIntoConstraints = false
 countryCountView.isUserInteractionEnabled = true
 view.addSubview(countryCountView)

 NSLayoutConstraint.activate([
      countryCountView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
      countryCountView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
      countryCountView.topAnchor.constraint(equalTo: headerContainer.bottomAnchor),
      countryCountView.heightAnchor.constraint(equalToConstant: 60)
 ])

我的UICollectionViewCell:

My UICollectionViewCell:

override init(frame: CGRect) {
        countryNameLabel = UILabel()
        countryUserCountLabel = UILabel()
        super.init(frame: frame)

        contentView.addSubview(countryNameLabel)
        countryNameLabel.translatesAutoresizingMaskIntoConstraints = false
        countryNameLabel.font = UIFont.boldSystemFont(ofSize: 13)
        countryNameLabel.textColor = .white

        contentView.addSubview(countryUserCountLabel)
        countryUserCountLabel.translatesAutoresizingMaskIntoConstraints = false
        countryUserCountLabel.font = UIFont.systemFont(ofSize: 13)
        countryUserCountLabel.textColor = .white

        NSLayoutConstraint.activate([
            countryNameLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
            countryNameLabel.heightAnchor.constraint(equalToConstant: 30),
            countryNameLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 5),
            countryNameLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5),
//            countryNameLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0),
//            countryNameLabel.widthAnchor.constraint(equalToConstant: 20),

            countryUserCountLabel.leadingAnchor.constraint(equalTo: countryNameLabel.trailingAnchor, constant: 5),
            countryUserCountLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 5),
            countryUserCountLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5),
            countryUserCountLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -5),
            countryUserCountLabel.heightAnchor.constraint(equalToConstant: 30),
//            countryUserCountLabel.widthAnchor.constraint(equalToConstant: 40)
        ])
    }

委托方法返回的高度:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 70, height: 40)
//        return CGSize.zero
    }

滚动之前:

滚动后:

设置 collectionView.showsHorizo​​ntalScrollIndicator = false 无效.

还设置 layout.estimatedItemSize = CGSize.zero 可以解决上移问题,但会阻止单元格正确调整大小.

Also setting layout.estimatedItemSize = CGSize.zero fixes the shifting up but stops the cells from resizing correctly.

推荐答案

由于设置了 layout.estimatedItemSize = CGSize.zero ,解决了布局移位问题,但并未相应地调整单元格的大小 您可能已经对集合视图的每个单元格中使用的标签的宽度约束进行了硬编码 .(就像您代码中对 viewTitleLabel 的约束一样)

Since setting layout.estimatedItemSize = CGSize.zero solves the layout shift issue but does not resize the cells accordingly, I'm guessing a possibility where you might have hardcoded the width constraint for the label used in each cell of your collection view. (Like the constraints from your code for viewTitleLabel)

假设是这种情况,并且您希望进行自动调整大小,则可以尝试删除硬编码的宽度约束.(如果有的话)

Assuming that this is the case and you want auto-resizing to take place, you can try removing the hardcoded width constraints. (If any)

要让自动布局发挥作用, UILabel 通常只需要X和Y位置约束,除非您需要严格控制边界

For auto-layout to do its magic, only the X and Y position constraints are usually needed for UILabel unless you need strict control over the boundaries

问题似乎与单元格约束的设置方式有关.这是细分:

The problem seems to be with the way the cell constraints are set up. Here's the breakdown:

出现上移是因为:

  1. 单元格最初加载了集合视图的高度,即50

  1. The cells are initially loaded with your collection view's height i.e: 50

由于已设置 layout.itemSize = UICollectionViewFlowLayout.automaticSize ,因此流布局将覆盖默认高度50,并根据其子视图约束设置来设置像元高度.

Since you've set layout.itemSize = UICollectionViewFlowLayout.automaticSize, the flow layout overrides the default height of 50 and sets the cell height according to its subview constraints setup.

您已将标签的 heightAnchor 指定为30,将 topAnchor 指定为5,将 bottomAnchor 指定为-5计算自动布局时,单元的整体高度为40

You've specified the label's heightAnchor to be 30, topAnchor to be 5, and the bottomAnchor to -5 making the cell's overall height to be 40 when calculating for autolayout

此高度从50切换到40会导致您的上移"动作.问题.

This height switch from 50 to 40 causes your "shift-up" issue.

要解决此问题:

  • 您可以将标签的 heightAnchor 更改为50,以与集合视图的高度匹配,设置其 centerYAnchor 并保持您的 layout.itemSize =UICollectionViewFlowLayout.automaticSize

  • You can change the label's heightAnchor to be 50 to match with the collection view's height, set its centerYAnchor and maintain your layout.itemSize = UICollectionViewFlowLayout.automaticSize

                        (OR)

  • 设置标签的 centerYAnchor 并手动指定高度为50的 layout.itemSize

  • Set the label's centerYAnchor and manually specify layout.itemSize with a height of 50

    这篇关于在父容器中滚动时,水平滚动集合视图将上移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 08-31 03:37