如何在 Swift 中以编程方式更改 UICollectionViewCell 大小?

Posted

技术标签:

【中文标题】如何在 Swift 中以编程方式更改 UICollectionViewCell 大小?【英文标题】:How to change UICollectionViewCell size programmatically in Swift? 【发布时间】:2015-07-27 19:59:18 【问题描述】:

我有一个UICollectionView 和一个segmented control 来在数据之间切换。但是如何以编程方式更改UICollectionViewCell size 属性?然后我可以为每种数据类型适当地自定义每种样式。

例如将宽度更改为 520 磅,将高度更改为 100。我是 ios 开发新手,并且对 CSS 很熟悉:/

我知道如何在 Xcode 中执行此操作(显然),但不知道正确的方法来快速更改它。非常感谢任何想法或反馈(Y)

【问题讨论】:

使用 collectionviewlayouts 方法或创建不同的 xibs 单元格。根据您的需要 【参考方案1】:

确保你的类符合 UICollectionViewDelegateFlowLayout (对于 swift4)

eg. class MyClass: UICollectionViewDelegateFlowLayout

在 Swift 3 之前

//Use for size
func collectionView(collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 

    
//Use for interspacing
    func collectionView(collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat 
            return 1.0
    

    func collectionView(collectionView: UICollectionView, layout
        collectionViewLayout: UICollectionViewLayout,
        minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat 
            return 1.0
    

// 对于 swift 3

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



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


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

// 对于 swift 4

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

        

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

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

对 swift 3 使用与上面所示相同的代码,但只需 确保 你的类符合协议 UICollectionViewDelegateFlowLayout

【讨论】:

非常感谢!我已经做到了,而且效果很好,我只是声明了var size = CGSize(width: 300, height: 100) 并返回了 size 属性。不确定如何添加边界半径的想法,将对此进行研究。当然,这不是需要使宽度适合每个设备的长期解决方案。 有趣的是,在 Xcode 7.3.1 中此方法没有自动完成功能。但如果你只是复制和粘贴,它就可以工作......【参考方案2】:

斯威夫特 3

如果您使用的是 Swift 3,则来自@sumit-oberoi 答案的方法不会被调用。要使其正常工作,请进行以下调整:

    符合UICollectionViewDelegateFlowLayout协议。

    实现这些方法:

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize 
    
    
    
    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
        return 1.0
    
    
    func collectionView(_ collectionView: UICollectionView, layout
        collectionViewLayout: UICollectionViewLayout,
                        minimumLineSpacingForSectionAt section: Int) -> CGFloat 
        return 1.0
    
    

注意变化:

    在方法名称中的collectionView之前添加_ NSIndexPath 更改为 IndexPath

【讨论】:

请问为什么会这样? 在 swift 3 中,这些方法名称已更改。 NSIndexPath 也被替换为 IndexPath。如果您有旧方法,则根本不会调用它们,因为它们不再在 CollectionView 数据源中定义。 但是为什么 Xocde 没有给出更改该方法参数的建议? 这些方法也没有在 swift 3(版本 8.2.1 (8C1002))中调用 所以这就是您节省我时间的方式。+1 投票.. UICollectionViewDelegateFlowLayout【参考方案3】:

斯威夫特 3

override func viewDidLoad() 
    super.viewDidLoad()

    let cellSize = CGSize(width:80 , height:80)

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .vertical //.horizontal
    layout.itemSize = cellSize
    layout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
    layout.minimumLineSpacing = 1.0
    layout.minimumInteritemSpacing = 1.0
    myCollectionView.setCollectionViewLayout(layout, animated: true)

    myCollectionView.reloadData()

【讨论】:

这对我来说是一个很好的答案,因为我没有继承 UICollectionController,而是从标准 UIViewController 访问 Outlet。当您尝试从 UIViewController 继承并遵守协议 UICollectionViewDelegateFlowLayout (UIViewController, UICollectionViewDelegateFlowLayout) 时,编译器会抱怨。【参考方案4】:

如果你使用 Gaurav Rami 的代码如下

let cellSize = CGSize(width:80 , height:80)

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical //.horizontal
layout.itemSize = cellSize
layout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
layout.minimumLineSpacing = 1.0
layout.minimumInteritemSpacing = 1.0
myCollectionView.setCollectionViewLayout(layout, animated: true)

并收到此消息“对未渲染的视图进行快照会导致快照为空。确保您的视图在快照之前或屏幕更新后的快照之前至少渲染过一次。” 在为集合视图设置视图布局时,您应该删除动画

myCollectionView.setCollectionViewLayout(layout, animated: false)

然后消息就会消失

【讨论】:

【参考方案5】:

尝试使用 UICollectionViewDelegateFlowLayout 方法。在 Xcode 11 或更高版本中,您需要在 storyboard 中将 Estimate Size 设置为 none。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
  let padding: CGFloat =  170
  let collectionViewSize = advertCollectionView.frame.size.width - padding
  return CGSize(width: collectionViewSize/2, height: collectionViewSize/2)

【讨论】:

感谢您将“估计大小设置为无”【参考方案6】:
    在情节提要中 选择 Collection View 并在 Size Inspector 中将 Estimate Size 属性设置为 NONE,如下所示:

    在 View Controller 中为 View Controller 添加 UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    let itemsPerRow:CGFloat = 2
    let padding:CGFloat = 20
    let itemWidth = (collectionView.bounds.width / itemsPerRow) - padding:CGFloat
    let itemHeight = collectionView.bounds.height - (2 * padding:CGFloat)
    return CGSize(width: itemWidth, height: itemHeight)

【讨论】:

【参考方案7】:

斯威夫特 5:

    符合 UICollectionViewDelegateFlowLayout 协议,这意味着您需要将该协议放在类的继承中或作为扩展。像这样:

    class ViewController: UIViewController, UICollectionViewDelegate, 
    UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 
    
    

    实现 sizeForItemAt 方法:

    func collectionView(_ collectionView: UICollectionView, 布局 collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: 索引路径)-> CGSize 返回CGSize(宽度:100,高度:100)

你可以在 CGSize 构造函数中放入你想要的宽度和高度。

【讨论】:

【参考方案8】:
     /// this method is used for flow layout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    let numberOfItemsPerRow:CGFloat = 3
    let spacingBetweenCells:CGFloat = 2

    // 2 is the value of sectionInset value
    
    let totalSpacing = (2 * 2) + ((numberOfItemsPerRow - 1) * spacingBetweenCells) //Amount of total spacing in a row
    if let collection = self.collectionAccounts
        let width = (collection.bounds.width - totalSpacing)/numberOfItemsPerRow
        
        return CGSize(width: width, height: width)
    else
        return CGSize(width: 0, height: 0)
    

【讨论】:

【参考方案9】:
first Conform protocol the UICollectionViewDelegateFlowLayout

set width and height  UICollectionViewCell 

UIcollectionViewCell Hight = 300;
UIcollectionViewCell Width = 380;

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,sizeForItemAt indexPath: IndexPath) -> CGSize 
      return CGSize(width: CGFloat((380)), height: CGFloat(300))
    

【讨论】:

这不是所有的代码 - 如果您将整个内容格式化为代码,它对任何人都没有帮助。只有代码应该被格式化为代码。就目前而言,您的贡献没有用。您还应该描述您的贡献提供了其他人没有提供的内容。

以上是关于如何在 Swift 中以编程方式更改 UICollectionViewCell 大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中以编程方式更改 UIButton 状态

如何在 Swift 中以编程方式更改自定义 UITableViewCell 中按钮的背景颜色?

在 Swift 中以编程方式更改 UIButton 的文本(填充)

当 UIStepper 在 Swift 4 中以编程方式点击时如何更改 UILabel 的文本,如果它们都在 UITableViewCell 中?

我可以在 Swift 5 和 IOS 12 中以编程方式更改 iOS 屏幕壁纸吗

在 Swift 中以编程方式隐藏 TextFields?