如何在 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 中?