UICollectionView单元格不占用UICollectionView的宽度

UICollectionView的宽度将随每个设备而改变,因为它被限制到达视图的水平边界。 collectionView的布局是Flow。 我使用UICollectionView的唯一原因是在不同的设备尺寸上均匀分布图像,所有这些图像都会有一个轻击手势识别器。 而行的数量是可变的,因为图像图标的数量会有所不同。 显然这是我之后的方法:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: collectionViewWidth/6, height: collectionViewWidth/6); } 

我试图这样做:

 var collectionViewWidth: CGFloat = 0.0 override func viewDidLoad() { super.viewDidLoad() collectionView.dataSource = self } override func viewDidAppear(animated: Bool) { collectionViewWidth = collectionView.collectionViewLayout .collectionViewContentSize().width } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: collectionViewWidth/6, height: collectionViewWidth/6); } 

但是我没有在代码中尝试任何东西,最终的输出是这样的(忘了不在UICollectionView中的图像 – 它们将被删除):

在这里输入图像说明

我改变了界面生成器的单元格大小,结果让我这个:

在这里输入图像说明

所以我有两个问题:

为什么上面图片中的单元格不能进入UICollectionView的边缘?

如何在运行时以编程方式设置单元大小,以使我的UICollectionView在所有设备大小上有6列?

这里是我的ViewController包含UICollectionView的所有代码:

 import UIKit class DressingRoomViewController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! let identifier = "cellIdentifier" let dataSource = DataSource() var collectionViewWidth: CGFloat = 0.0 override func viewDidLoad() { super.viewDidLoad() collectionView.dataSource = self } override func viewDidAppear(animated: Bool) { collectionViewWidth = collectionView.collectionViewLayout .collectionViewContentSize().width } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func prepareForSegue( segue: UIStoryboardSegue, sender: AnyObject?) { if (segue.identifier == "dressingRoom2MyOutfits") { let myOutfitsViewController = segue.destinationViewController as! MyOutfitsViewController } } } // MARK:- UICollectionViewDataSource Delegate extension DressingRoomViewController : UICollectionViewDataSource { func numberOfSectionsInCollectionView( collectionView: UICollectionView) -> Int { return dataSource.groups.count } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dataSource.numbeOfRowsInEachGroup(section) } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier( identifier,forIndexPath:indexPath) as! FruitCell let fruits: [Fruit] = dataSource.fruitsInGroup(indexPath.section) let fruit = fruits[indexPath.row] let name = fruit.name! cell.imageView.image = UIImage(named: name) cell.caption.text = name.capitalizedString return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: collectionViewWidth/6, height: collectionViewWidth/6); } } 

可能值得一提的是,我的UICollectionView的数据源是分组的,只是因为我正在做一个教程。 这里是数据源代码:

class DataSource {

 init() { populateData() } var fruits:[Fruit] = [] var groups:[String] = [] func numbeOfRowsInEachGroup(index: Int) -> Int { return fruitsInGroup(index).count } func numberOfGroups() -> Int { return groups.count } func gettGroupLabelAtIndex(index: Int) -> String { return groups[index] } // MARK:- Populate Data from plist func populateData() { if let path = NSBundle.mainBundle().pathForResource( "Fruits", ofType: "plist") { if let dictArray = NSArray(contentsOfFile: path) { for item in dictArray { if let dict = item as? NSDictionary { let name = dict["name"] as! String let group = dict["group"] as! String let fruit = Fruit(name: name, group: group) if !contains(groups, group){ groups.append(group) } fruits.append(fruit) } } } } } // MARK:- FruitsForEachGroup func fruitsInGroup(index: Int) -> [Fruit] { let item = groups[index] let filteredFruits = fruits.filter { (fruit: Fruit) -> Bool in return fruit.group == item } return filteredFruits } 

}

这里是加载到数据源中的plist:

在这里输入图像说明

编辑:我已经做了一些工作,删除组,因为他们不需要。 我看到这些组织正在造成新的行太早。 我改变了这个代码:

  // MARK:- UICollectionViewDataSource Delegate extension DressingRoomViewController : UICollectionViewDataSource { func numberOfSectionsInCollectionView( collectionView: UICollectionView) -> Int { return 1 } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 12 } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier( identifier,forIndexPath:indexPath) as! FruitCell let fruits: [Fruit] = dataSource.fruits let fruit = fruits[indexPath.row] let name = fruit.name! cell.imageView.image = UIImage(named: name) cell.caption.text = name.capitalizedString return cell } func collectionView(collectionView: UICollectionView, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: 200, height: 200); } } 

在这里输入图像说明

现在我只需要将单元格宽度的1/6作为收集视图的宽度,然后裁剪UICollectioView的底部就是浪费的空间

您可以在viewDidLoad中设置collectionViewLayout的itemSize,如下例所示:

  override func viewDidLoad() { super.viewDidLoad() let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout let collectionViewSize = collectionView.frame.size let nrOfCellsPerRow = 6 let itemWidth = collectionViewSize.width/nrOfCellsPerRow let itemHeight = 80 // example layout.itemSize = CGSize(width: itemWidth, height: itemHeight) } 

如果你想在单元格之间有空格,你将不得不补偿itemWidth的计算

如果您使用的是UICollectionViewFlowLayout,则configuration单元格宽度的方式是通过与UICollectionViewFlowLayout进行交谈。 设置itemSize

对于布局,我们基本上更喜欢创build一个从UICollectionViewFlowlayoutinheritance的CustomflowLayout,并且提供了两种方法:

  • layoutAttributesForElementsInRect:(必填)
  • layoutAttributesForItemAtIndexPath :(必需)

然后设置

[self.collectionview setFlowlayout:CustomflowLayout];