【发布时间】:2015-08-25 14:23:18
【问题描述】:
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 列?
这是包含 UICollectionView 的 ViewController 的所有代码:
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 的数据源只是因为我在做一个教程而被分组。这是数据源代码:
类数据源{
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 的底部,这只是浪费空间
【问题讨论】:
-
您以前使用过集合视图吗? - 另外,让我问你这个问题:你是否尝试过设置断点或记录以查看事情发生的顺序?如果集合视图设置自己之前你的
viewDidAppear:配置你的宽度值?这会发生吗? -
@matt 不,我没有。我是 iOS 新手。我已经在 Team Treehouse 上完成了iOS with Swift track,现在我正在自己制作我的第一个应用程序。我只是在设置 collectViewWidth 变量后放置了一个断点,它在 iPhone4 上设置为 288。但是
func collectionView(collectionView: UICollectionView, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: 20, height: 20); }函数永远不会触发断点。也许这不是故意的,就像配置 collectionView 一样。 -
@matt 我已经尝试将值硬编码到上述设置单元格大小的函数中,但它没有改变输出
-
我建议先了解集合视图,然后再尝试以奇怪的方式弄乱它们。同时,我给出了一个答案,希望能为您指明正确的方向。
标签: ios uicollectionview