在父容器中滚动时水平滚动集合视图向上移动 [英] Horizontal scrolling collection view shifts up when scrolled in parent container

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

问题描述

我在父 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: <)
    }

对我的子视图的限制:

 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,手动指定layout.itemSize,高度为50

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

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

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆