ios UICollectionView 自定义单元格在 Swift 中填充宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29986379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UICollectionView Custom Cell to fill width In Swift
提问by AaoIi
I've been trying to figure-out how can i make the cell fill the width, as you can see in the picture the width between the cells is too big. i am using custom cell with only one imageView.
我一直在试图弄清楚如何让单元格填充宽度,正如您在图片中看到的那样,单元格之间的宽度太大。我正在使用只有一个 imageView 的自定义单元格。
I tried to customize it from the storyboard but i guess there is no option for that or it should be done programmatically.
我试图从情节提要中自定义它,但我想没有选择,或者应该以编程方式完成。
my UICollectionViewController :
我的 UICollectionViewController :
@IBOutlet var collectionView2: UICollectionView!
let recipeImages = ["angry_birds_cake", "creme_brelee", "egg_benedict", "full_breakfast", "green_tea", "ham_and_cheese_panini", "ham_and_egg_sandwich", "hamburger", "instant_noodle_with_egg.jpg", "japanese_noodle_with_pork", "mushroom_risotto", "noodle_with_bbq_pork", "starbucks_coffee", "thai_shrimp_cake", "vegetable_curry", "white_chocolate_donut"]
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
//#warning Incomplete method implementation -- Return the number of sections
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//#warning Incomplete method implementation -- Return the number of items in the section
return recipeImages.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! RecipeCollectionViewCell
// Configure the cell
cell.recipeImageView.image = UIImage(named: recipeImages[indexPath.row])
return cell
}
回答by Matthew Quiros
You need to do this programatically.
您需要以编程方式执行此操作。
Implement UICollectionViewDelegateFlowLayout
in your view controller and provide the size in collectionView:layout:sizeForItemAtIndexPath:
UICollectionViewDelegateFlowLayout
在您的视图控制器中实现并提供大小collectionView:layout:sizeForItemAtIndexPath:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let kWhateverHeightYouWant = 100
return CGSizeMake(collectionView.bounds.size.width, CGFloat(kWhateverHeightYouWant))
}
You will also want to call collectionView.collectionViewLayout.invalidateLayout()
inside your view controller's viewWillLayoutSubviews()
so that when the main view's dimensions change (on rotation, for example), the collection view is re-laid out.
您还需要collectionView.collectionViewLayout.invalidateLayout()
在视图控制器内部调用,viewWillLayoutSubviews()
以便当主视图的尺寸发生变化时(例如,在旋转时),集合视图会重新布局。
Swift 4 Update
斯威夫特 4 更新
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let kWhateverHeightYouWant = 100
return CGSize(width: collectionView.bounds.size.width, height: CGFloat(kWhateverHeightYouWant))
}
回答by mustafa
Inside your view controller override viewDidLayoutSubviews
method
在您的视图控制器覆盖viewDidLayoutSubviews
方法中
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
let itemWidth = view.bounds.width / 3.0
let itemHeight = layout.itemSize.height
layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
layout.invalidateLayout()
}
}
(collectionView
property is your collectionView)
(collectionView
属性是你的 collectionView)
回答by Nimit Parekh
Use Following code for set the width of UICollectionViewCell
.
使用以下代码设置UICollectionViewCell
.
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: screenWidth/3, height: screenWidth/3);
}
回答by brycejl
Also in Swift 3,
同样在 Swift 3 中,
Make sure your view controller complies with the following:
确保您的视图控制器符合以下要求:
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout
UICollectionViewDelegate、
UICollectionViewDataSource、
UICollectionViewDelegateFlowLayout
回答by Raju Abe
I have the same requirement, in my case below solution is worked. I set UIImageViewtop, left, bottom and right constraints to 0inside UICollectionviewCell
我有同样的要求,就我而言,以下解决方案有效。我在 UICollectionviewCell中将UIImageView顶部、左侧、底部和右侧约束设置为0
@IBOutlet weak var imagesCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// flowlayout
let screenWidth = UIScreen.main.bounds.width
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 10, right: 0)
layout.itemSize = CGSize(width: screenWidth/3 - 5, height: screenWidth/3 - 5)
layout.minimumInteritemSpacing = 5
layout.minimumLineSpacing = 5
imagesCollectionView.collectionViewLayout = layout
}
回答by JPetric
Swift 3
斯威夫特 3
If you are using swift 3, use this method:
如果您使用的是 swift 3,请使用以下方法:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
}
Notice the changes:
注意变化:
- add
_
beforecollectionView
in the method name NSIndexPath
changes toIndexPath
- 在方法名称
_
之前添加collectionView
NSIndexPath
更改为IndexPath
回答by Eduardo Irias
In my case, assuming every cell has a width of 155 and a height of 220. If I want to show 2 cells per row in a portrait mode and 3 for landscape.
就我而言,假设每个单元格的宽度为 155,高度为 220。如果我想在纵向模式下每行显示 2 个单元格,在横向模式下显示 3 个单元格。
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
var itemsCount : CGFloat = 2.0
if UIApplication.sharedApplication().statusBarOrientation != UIInterfaceOrientation.Portrait {
itemsCount = 3.0
}
return CGSize(width: self.view.frame.width/itemsCount - 20, height: 220/155 * (self.view.frame.width/itemsCount - 20));
}
回答by ZaBlanc
The best solution is to change the itemSize
of your UICollectionViewFlowLayout
in viewDidLayoutSubviews
. That is where you can get the most accurate size of the UICollectionView
. You don't need to call invalidate on your layout, that will be done for you already.
最好的解决方案是更改itemSize
您的UICollectionViewFlowLayout
in viewDidLayoutSubviews
. 在这里您可以获得最准确的UICollectionView
. 您不需要在布局上调用 invalidate ,这已经为您完成了。
回答by Firas Shrourou
For my case, I wanted to show two columns and 3 rows in the UICollectionView
就我而言,我想在 UICollectionView 中显示两列和 3 行
I added UICollectionViewDelegateFlowLayout delegate to my class
我在我的班级中添加了 UICollectionViewDelegateFlowLayout 委托
then I override sizeForItemAt indexPath
然后我覆盖 sizeForItemAt indexPath
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellHeight = (collectionView.bounds.size.height - 30) / 3 // 3 count of rows to show
let cellWidth = (collectionView.bounds.size.width - 20) / 2 // 2 count of colomn to show
return CGSize(width: CGFloat(cellWidth), height: CGFloat(cellHeight))
}
The 30 is the Line spacing, the 20 is the insent between cells
30 是行间距,20 是单元格之间的间隔
回答by froggomad
For my case, autolayout was only allowing the cell to grow to its content size even though I overrode the cell size in the storyboard, conformed to UICollectionViewDelegateFlowLayout
, and implemented sizeForItemAt
. So I made a dummy UIView the width of the cell's bounds.
对于我的情况下,自动布局才被允许细胞长到即使我在故事板推翻细胞大小的内容大小,符合UICollectionViewDelegateFlowLayout
和执行sizeForItemAt
。所以我做了一个虚拟的 UIView 单元格边界的宽度。
UICollectionViewController:
UICollectionViewController:
extension CollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.bounds.width - 40
return CGSize(width: width, height: collectionView.bounds.height / 3)
}
}
Cell (I'm calling this method on dependency injection):
Cell(我在依赖注入时调用此方法):
private func updateViews() {
let padding:CGFloat = 8
let innerView = UIView()
innerView.translatesAutoresizingMaskIntoConstraints = false
innerView.layer.cornerRadius = 8
innerView.layer.borderColor = UIColor.black.cgColor
innerView.layer.borderWidth = 1
contentView.addSubview(innerView)
NSLayoutConstraint.activate([
innerView.widthAnchor.constraint(equalToConstant: bounds.width - padding*2),
innerView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor, constant: padding),
innerView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor, constant: -padding),
innerView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: padding),
innerView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -padding)
])
}