可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to implement a CollectionView
.
When I am using Autolayout, my cells won't change the size, but their alignment.
Now I would rather want to change their sizes to e.g.
//var size = CGSize(width: self.view.frame.width/10, height: self.view.frame.width/10)
I tried setting in my CellForItemAtIndexPath
collectionCell.size = size
it didn't work though.
Is there a way to achieve this?
edit:
It seems, that the answers will only change my CollectionView width and height itself. Is there are conflict in Constraints possible? Any ideas on that ?
回答1:
Use this method to set custom cell height width.
Make sure to add this protocols
UICollectionViewDelegate
UICollectionViewDataSource
UICollectionViewDelegateFlowLayout
If you are using swift 5 or xcode 11 and later you need to set Estimate Size
to none
using storyboard in order to make it work properly. If you will not set that than below code will not work as expected.
Swift 4 or Later
extension YourViewController: UICollectionViewDelegate {
//Write Delegate Code Here
}
extension YourViewController: UICollectionViewDataSource {
//Write DataSource Code Here
}
extension YourViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: screenWidth, height: screenWidth)
}
}
Objective-C
@interface YourViewController : UIViewController<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.frame), (CGRectGetHeight(collectionView.frame)));
}
回答2:
Make sure to add the protocol UICollectionViewDelegateFlowLayout
in your class
declaration
class MyCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout
{
//MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: 100.0, height: 100.0)
}
}
回答3:
If one is using storyboard and overriding UICollectionViewDelegateFlowLayout then in swift 5 and Xcode 11 also set Estimate size to None
回答4:
Finally got the answer.
You should extend UICollectionViewDelegateFlowLayout
This should be working with answers above.
回答5:
swift 4.1
You have 2 ways in order to change the size of CollectionView.
First way -> add this protocol UICollectionViewDelegateFlowLayout
for
In my case I want to divided cell into 3 part in one line. I did this code below
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource ,UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
// In this function is the code you must implement to your code project if you want to change size of Collection view
let width = (view.frame.width-20)/3
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return collectionData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath)
if let label = cell.viewWithTag(100) as? UILabel {
label.text = collectionData[indexPath.row]
}
return cell
}
}
Second way -> you don't have to add UICollectionViewDelegateFlowLayout but you have to write some code in viewDidload function instead as code below
class ViewController: UIViewController {
@IBOutlet weak var collectionView1: UICollectionView!
var collectionData = ["1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.", "9.", "10.", "11.", "12."]
override func viewDidLoad() {
super.viewDidLoad()
let width = (view.frame.width-20)/3
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: width)
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return collectionData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath)
if let label = cell.viewWithTag(100) as? UILabel {
label.text = collectionData[indexPath.row]
}
return cell
}
}
Whatever you write a code as the first way or second way you will get the same result as above. I wrote it. It worked for me
回答6:
Size ratio according to iPhone size :
Here's what you can do to have different width and height for cell's regarding the iPhone size :
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let width = (self.view.frame.size.width - 12 * 3) / 3 //some width
let height = width * 1.5 //ratio
return CGSize(width: width, height: height)
}
And maybe you should also disable your AutoLayout constraints on cell for this answer to work.
回答7:
The collection view has a layout object. In your case, it is probably a flow layout (UICollectionViewFlowLayout). Set the flow layout's itemSize
property.
回答8:
in Swift3 and Swift4 you can change cell size by adding UICollectionViewDelegateFlowLayout and implementing it's like this :
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 100)
}
or if create UICollectionView programmatically you can do it like this :
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal //this is for direction
layout.minimumInteritemSpacing = 0 // this is for spacing between cells
layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height) //this is for cell size
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
回答9:
swift4 swift 4 ios collection view collectionview example xcode latest code working sample
Add this on Delegate section of the top
UICollectionViewDelegateFlowLayout
and use this function
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (self.view.frame.size.width - 20) / 3 //some width
let height = width * 1.5 //ratio
return CGSize(width: width, height: height)
}
/////
sample complete code
create on collection view and collectionview cell in storyboard give reference to the collection as
@IBOutlet weak var cvContent: UICollectionView!
paste this in View controller
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var arrVeg = [String]()
var arrFruits = [String]()
var arrCurrent = [String]()
@IBOutlet weak var cvContent: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
arrVeg = ["Carrot","Potato", "Tomato","Carrot","Potato", "Tomato","Carrot","Potato", "Tomato","Carrot","Potato", "Tomato"]
arrVeg = ["Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange","Mango","Papaya","Orange"]
arrCurrent = arrVeg
}
//MARK: - CollectionView
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (self.view.frame.size.width - 20) / 3 //some width
let height = width * 1.5 //ratio
return CGSize(width: width, height: height)
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrCurrent.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ContentCollectionViewCell
cell.backgroundColor = UIColor.green
return cell
}
}
回答10:
Try below method
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: 100.0, height: 100.0)
}
回答11:
Swift 5 Programmatically
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
//Provide Width and Height According to your need
let cellWidth = UIScreen.main.bounds.width / 10
let cellHeight = UIScreen.main.bounds.height / 10
layout.itemSize = CGSize(width: cellWidth, height: cellHeight)
//You can also provide estimated Height and Width
layout.estimatedItemSize = CGSize(width: cellWidth, height: cellHeight)
//For Setting the Spacing between cells
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
return UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
}()
回答12:
**Swift 5**
To make this work you have to do the following.
Add these protocols
- UICollectionViewDelegate
- UICollectionViewDataSource
- UICollectionViewDelegateFlowLayout
Your code will then look like this
extension YourViewController: UICollectionViewDelegate {
//Write Delegate Code Here
}
extension YourViewController: UICollectionViewDataSource {
//Write DataSource Code Here
}
extension YourViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: screenWidth, height: screenWidth)
}
}
Now the final and crucial step to see this take effect is to go to your viedDidLoad function inside your Viewcontroller.
override func viewDidLoad() {
super.viewDidLoad()
collection.dataSource = self // Add this
collection.delegate = self // Add this
// Do any additional setup after loading the view.
}
Without telling your view which class the delegate is it won't work.
回答13:
An other way is to set the value directly in the flow layout
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: size, height: size)
回答14:
This is my version, find your suitable ratio to get the cell size as per your requirement.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.frame)/4, CGRectGetHeight(collectionView.frame)/4);
}