Swift:CollectionView单元格大小

3

我有一个collectionView,它有一个到父视图的约束。我想在iPhone X上获得这个结果:

enter image description here

但我得到了这个:

enter image description here

如何修复它?

代码:

func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 4
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {


        cellOffset = 10

        cellWidth = (667 / 3)  - (cellOffset * 4)
        cellHeight =  (cellWidth / 2 * 3) + (cellWidth / 2 * 0.65)

        return CGSize(width: cellWidth, height: cellHeight)
    }

更新

输入图像描述

更新

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let sectionInset = collectionView.frame.width / 3.0
        let margins = CGFloat(10.0 * 2.0)
        let width = (collectionView.frame.width - sectionInset - margins) / 3.0
        let height = collectionView.frame.height - 40.0

        let collectionViewLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
        collectionViewLayout?.sectionInset = UIEdgeInsets(top: 0, left: 6.0, bottom: 0, right: 6.0)
        collectionViewLayout?.minimumInteritemSpacing = 10
        collectionViewLayout?.invalidateLayout()

        return CGSize(width: width, height: height)
    }

结果:

在此输入图片描述


(注:该内容无需翻译,已为中文)
5个回答

1
如果您想在横向方向上有3个单元格。
let cellWidth = ( self.collectionView.frame.width - 2 * cellOffset ) / 3

在这种情况下,我的单元格高度被屏幕遮挡。而宽度太大(回到安全区域)。我想使用类似于iPhone 8屏幕的667。并且我还想获得3个单元格,使其与屏幕之间的空间相同。 - user291334
我想一次只显示3个单元格。对于所有设备,我使用self.collectionView.frame.width,它运行良好。在这段代码中,我保持了我想要的比例。但是,如果我将此代码用于iPhone X,则我的单元格高度会隐藏在屏幕后面。如果我更改单元格高度而不更改单元格宽度,则会破坏比例。 - user291334
根据您的纵横比尝试打印高度为零。 - Shehata Gamal
宽度也会改变吗? - user291334
像这样 height = width/4 - user291334
显示剩余13条评论

0
 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {



    return CGSize(width: collectionView.frame.size.width/4 - 1, height: collectionView.frame.size.width/4 - 1)
}

对于所有设备,一切都正常。但是当我在我的iPhone X上启动应用程序时,单元格位于中间,并且与左侧屏幕边缘和右侧屏幕边缘之间的距离相同。但是,当我点击collectionView或开始滚动时,我的单元格会向左移动到屏幕边缘,如果我继续滚动,我的其他部分在numberOfSections(in collectionView: UICollectionView)中将不会处于中间位置。 - user291334
当应用程序启动时,我的collectionView未出现在中心位置-https://streamable.com/c4kpx - user291334

0
我的建议是考虑重构您的布局,使每个部分左右缩进所需的边距。然后,您可以按以下方式描述单元格大小:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let sectionInset = collectionView.frame.width / 3.0
    let margins = CGFloat(10.0 * 2.0)
    let width = (collectionView.frame.width - sectionInset - margins) / 3.0
    let height = collectionView.frame.height - 40.0

    return CGSize(width: width, height: height)
}

接下来,您需要在适当的委托方法中返回此部分插入值。假设您想为集合视图保留第一个和最后一个六分之一的边距,这大致是您的图像显示的内容。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0,
                        left: collectionView.frame.width / 6.0,
                        bottom: 0,
                        right: collectionView.frame.width / 6.0)
}

将所有内容综合起来,我们最终得到了这个版本:
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 4
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let sectionInset = collectionView.frame.width / 3.0
    let margins = CGFloat(10.0 * 2.0)
    let width = (collectionView.frame.width - sectionInset - margins) / 3.0
    let height = collectionView.frame.height - 40.0

    return CGSize(width: width, height: height)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 10.0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0,
                        left: collectionView.frame.width / 6.0,
                        bottom: 0,
                        right: collectionView.frame.width / 6.0)
}

我不太理解你的代码。在“section inset”、“cell margins”和“ratio”中,我应该粘贴什么值?还有你的代码的两个部分——“(UIEdgeInsets)”如何使用? - user291334
我编辑了我的答案以提供更多细节,并测试了结果。如果你想看到更流畅的分页行为,你应该尝试 collectionView.isPagingEnabled = true - woodcutting
这是一项工作。但这是iPhone X的一个好解决方案。对于其他设备,我想在我的问题中保存代码(将更改667为view.frame.width)。因为在我的代码中,我有一个特殊的单元格方面。而在您的代码中,我的其他设备方面会出现问题。如何仅针对iPhone X实现您的代码? - user291334
你想使用的宽高比在不同设备上是一致的吗?如果是,你可以将确定高度的行改为只使用你的宽高比。 - woodcutting
如果有必要检查设备类型,这里提供了一些检查设备类型的建议。 - woodcutting
显示剩余2条评论

0

你需要通过这个来设置集合视图的布局。

// setup collection view
let numberItemPerRow = 4
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
layout.itemSize = CGSize(width: ScreenSize.width/numberItemPerRow-1, 
                         height: ScreenSize.width/numberItemPerRow)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
your_collection.collectionViewLayout = layout

我保证这段代码会被解决的!!


当应用程序启动时,我的collectionView未出现在中心位置-https://streamable.com/c4kpx - user291334

0

你把它搞得有点复杂了。只需要稍微调整一下插图和大小就可以了。这是示例代码:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsetsMake(0, 145, 0, 145)
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 4
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    indePath = indexPath
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: self.view.frame.width / 3 - 100 , height: collectionView.frame.size.height - 100)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 5
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 5
}

这是它所给出的图像:

enter image description here

更新

import UIKit

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {

    lazy var collectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .green
        cv.isPagingEnabled = true
        cv.delegate = self
        cv.dataSource = self
        return cv
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(collectionView)
        collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
        collectionView.frame = self.view.frame
        collectionView.contentInset = UIEdgeInsetsMake(0, -45, 0, -45)
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(0, 145, 0, 145)
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 4
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.view.frame.width / 3 - 100 , height: collectionView.frame.size.height - 100)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 5
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 5
    }

}

class Cell : UICollectionViewCell {


    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {
        self.backgroundColor = .red
    }

}

它可以工作,但我在collectionView方面遇到了一些问题。当应用程序启动时,我的collectionView出现在中心位置之外-https://streamable.com/c4kpx - user291334
只需设置collectionView.contentInset。在我给你的示例中,这些值为collectionView.contentInset = UIEdgeInsetsMake(0, -45, 0, -45)。 - Galo Torres Sevilla
但在这种情况下,单元格大小不同。 - user291334
这并没有帮助。请看滚动指示器,问题仍然存在。https://streamable.com/eh77l - user291334
你到底在做什么?当然,如果你的单元格从集合视图的边缘扩展并设置了负内容插入,则会发生这种情况。负值是你在问题中首先描述的。这里是工作示例:https://streamable.com/3h6n3 - Galo Torres Sevilla
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接