[英]UICollectionView Custom Cell to fill width In Swift
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
}
You need to do this programatically.您需要以编程方式执行此操作。
Implement UICollectionViewDelegateFlowLayout
in your view controller and provide the size in collectionView:layout:sizeForItemAtIndexPath:
在视图控制器中实现
UICollectionViewDelegateFlowLayout
并在collectionView:layout:sizeForItemAtIndexPath:
提供大小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.您还需要在视图控制器的
viewWillLayoutSubviews()
调用collectionView.collectionViewLayout.invalidateLayout()
以便当主视图的尺寸发生变化时(例如在旋转时),集合视图会重新布局。
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let kWhateverHeightYouWant = 100
return CGSize(width: collectionView.bounds.size.width, height: CGFloat(kWhateverHeightYouWant))
}
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)
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);
}
Also in Swift 3,同样在 Swift 3 中,
Make sure your view controller complies with the following:确保您的视图控制器符合以下要求:
UICollectionViewDelegate, UICollectionViewDelegate,
UICollectionViewDataSource, UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout UICollectionViewDelegateFlowLayout
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:注意变化:
_
before collectionView
in the method namecollectionView
前添加_
NSIndexPath
changes to IndexPath
NSIndexPath
更改为IndexPath
I have the same requirement, in my case below solution is worked.我有同样的要求,就我而言,以下解决方案有效。 I set UIImageView top, left, bottom and right constraints to 0 inside 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
}
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 是单元格之间的间隔
以编程方式将itemSize
设置为[UIScreen mainScreen].bounds.size.width/3
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));
}
The best solution is to change the itemSize
of your UICollectionViewFlowLayout
in viewDidLayoutSubviews
.最好的解决方案是在
viewDidLayoutSubviews
更改itemSize
的UICollectionViewFlowLayout
。 That is where you can get the most accurate size of the UICollectionView
.这是您可以获得
UICollectionView
最准确大小的UICollectionView
。 You don't need to call invalidate on your layout, that will be done for you already.您不需要在布局上调用 invalidate ,这已经为您完成了。
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
.就我而言,即使我覆盖了情节
UICollectionViewDelegateFlowLayout
的单元格大小,符合UICollectionViewDelegateFlowLayout
并实现了sizeForItemAt
,自动布局也只允许单元格增长到其内容大小。 So I made a dummy UIView the width of the cell's bounds.所以我做了一个虚拟的 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)
])
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.