CollectionView 在 tableViewCell 数据显示
Posted
技术标签:
【中文标题】CollectionView 在 tableViewCell 数据显示【英文标题】:CollectionView in tableViewCell data display 【发布时间】:2015-07-16 09:26:50 【问题描述】:我在每个 tableViewCell 中嵌入了一个 collectionView。在每个 tableViewWillDisplayCell 事件中,我为我的 collectionView 设置了正确的 dataSource,然后在 collectionView 中重新加载数据。
代码如下:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
let c = cell as! CustomTableViewCell
c.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, indexPath: indexPath)
CustomTableViewCell.swift:
class CustomTableViewCell: UITableViewCell
var collectionView: indexedCollectionView!
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
layout.itemSize = CGSizeMake(5, 5)
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
self.collectionView = indexedCollectionView(frame: CGRectZero, collectionViewLayout: layout)
self.collectionView.registerClass(UICollectionViewCell.classForCoder(), forCellWithReuseIdentifier: collectionViewCellIdentifier as String)
self.collectionView.backgroundColor = UIColor.whiteColor()
self.collectionView.showsHorizontalScrollIndicator = false
self.contentView.addSubview(self.collectionView)
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
override func layoutSubviews()
super.layoutSubviews()
self.collectionView.frame = self.contentView.bounds;
func setCollectionViewDataSourceDelegate(dataSourceDelegate delegate: protocol<UICollectionViewDelegate,UICollectionViewDataSource>, indexPath: NSIndexPath)
self.collectionView.dataSource = delegate
self.collectionView.delegate = delegate
self.collectionView.indexPath = indexPath
self.collectionView.tag = indexPath.row
self.collectionView.reloadData()
TableViewController.swift:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell: UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! UICollectionViewCell
let tableViewCell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forItem: collectionView.tag, inSection: 0))
var rect: CGRect?
var label: UILabel = UILabel()
label.font = UIFont(name: "HelveticaNeue-Light", size: 18.0)
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.textAlignment = .Center
switch indexPath.row
case 0:
cell.frame = CGRectMake(0, 0, tableViewCell!.frame.width * 0.2, tableViewCell!.frame.height)
rect = cell.bounds
label.frame = rect!
label.text = events[collectionView.tag].category
break
case 1:
cell.frame = CGRectMake(tableViewCell!.frame.width * 0.2, 0, tableViewCell!.frame.width * 0.3, tableViewCell!.frame.height)
rect = cell.bounds
label.frame = rect!
label.text = events[collectionView.tag].event
break
case 2:
cell.frame = CGRectMake(tableViewCell!.frame.width * 0.5, 0, tableViewCell!.frame.width * 0.26, tableViewCell!.frame.height)
rect = cell.bounds
label.frame = rect!
label.text = events[collectionView.tag].location
break
case 3:
cell.frame = CGRectMake(tableViewCell!.frame.width * 0.76, 0, tableViewCell!.frame.width * 0.12, tableViewCell!.frame.height)
rect = cell.bounds
label.frame = rect!
label.text = events[collectionView.tag].date
break
case 4:
cell.frame = CGRectMake(tableViewCell!.frame.width * 0.88, 0, tableViewCell!.frame.width * 0.12, tableViewCell!.frame.height)
rect = cell.bounds
label.frame = rect!
label.text = events[collectionView.tag].time
break
default:
break
cell.addSubview(label)
cell.layer.borderColor = UIColor.blackColor().CGColor
cell.layer.borderWidth = 0.5
return cell
当应用程序启动时,一切看起来都很好 (screenshot),但是当我滚动我的 tableView 时,它变成为每个触发其 collectionView 的 reloadData 的单元格再次触发 tableView willDisplayCell 事件。
但效果不佳 (screenshot)。有人可以帮我解决我的问题吗?
更新:
我试图重新编写我的代码,但我遇到了问题。这是我的全部代码:
class TableViewController: UITableViewController //, UICollectionViewDataSource, UICollectionViewDelegate
var events: [Event] = [
Event(category: "GAA - Football Campionship", event: "Round 4A Munster Final Runner up v Round 3A Winner", location: "Semple Stadium - Thurles", date: "7/12/15", time: "2:00pm"),
Event(category: "Football", event: "Round 4A Munster", location: "Thurles", date: "7/2/15", time: "All day"),
Event(category: "Golf - 4 Majors", event: "U.S. Open Day 4 ( Final Day)", location: "Oakmont Country Club, Pennsylvania", date: "7/12/15", time: ""),
]
override func viewDidLoad()
super.viewDidLoad()
//self.tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "Cell")
self.tableView.separatorStyle = .None
self.tableView.tableFooterView = UIView(frame: CGRectZero)
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return events.count
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
var cell: CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? CustomTableViewCell
if cell == nil
cell = CustomTableViewCell.CreateCustomCell()
cell!.event = events[indexPath.row]
cell!.size = CGSize(width: cell!.frame.width, height: cell!.frame.height)
cell!.collectionView.reloadData()
cell!.clipsToBounds = true
return cell!
// override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
// let c = cell as! CustomTableViewCell
// c.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, indexPath: indexPath)
//
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
var cellHeight: CGFloat = 0.0
let screenWidth: CGFloat = UIScreen.mainScreen().bounds.width
var question: NSString = events[indexPath.row].category
var size = CGSizeMake(screenWidth * 0.2, 9999)
var textRect = question.boundingRectWithSize(size, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 18.0)!], context: nil)
size = textRect.size
cellHeight = size.height
question = events[indexPath.row].event
size = CGSizeMake(screenWidth * 0.3, 9999)
textRect = question.boundingRectWithSize(size, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 18.0)!], context: nil)
size = textRect.size
if cellHeight < size.height
cellHeight = size.height
question = events[indexPath.row].location
size = CGSizeMake(screenWidth * 0.3, 9999)
textRect = question.boundingRectWithSize(size, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 18.0)!], context: nil)
size = textRect.size
if cellHeight < size.height
cellHeight = size.height
question = events[indexPath.row].date
size = CGSizeMake(screenWidth * 0.1, 9999)
textRect = question.boundingRectWithSize(size, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 18.0)!], context: nil)
size = textRect.size
if cellHeight < size.height
cellHeight = size.height
question = events[indexPath.row].time
size = CGSizeMake(screenWidth * 0.1, 9999)
textRect = question.boundingRectWithSize(size, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 18.0)!], context: nil)
size = textRect.size
if cellHeight < size.height
cellHeight = size.height
return cellHeight
CustomTableViewCell.swift:
class CustomTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate
//var collectionView: UICollectionView!
@IBOutlet weak var collectionView: UICollectionView!
var event: Event?
var size: CGSize?
override func awakeFromNib()
super.awakeFromNib()
println("awake")
var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
layout.itemSize = CGSizeMake(5, 5)
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
collectionView.collectionViewLayout = layout
//self.collectionView = indexedCollectionView(frame: CGRectZero, collectionViewLayout: layout)
collectionView.registerClass(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
collectionView.backgroundColor = UIColor.whiteColor()
collectionView.showsHorizontalScrollIndicator = false
var cNib:UINib? = UINib(nibName: "CustomCollectionViewCell", bundle: nil)
collectionView.registerNib(cNib, forCellWithReuseIdentifier: "CollectionViewCell")
collectionView.frame = self.bounds
//self.contentView.addSubview(self.collectionView)
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
// var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
// layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
// layout.itemSize = CGSizeMake(5, 5)
// layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
// self.collectionView = indexedCollectionView(frame: CGRectZero, collectionViewLayout: layout)
// self.collectionView.registerClass(UICollectionViewCell.classForCoder(), forCellWithReuseIdentifier: collectionViewCellIdentifier as String)
// self.collectionView.backgroundColor = UIColor.whiteColor()
// self.collectionView.showsHorizontalScrollIndicator = false
// self.contentView.addSubview(self.collectionView)
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
// override func layoutSubviews()
// super.layoutSubviews()
// self.collectionView.frame = self.contentView.bounds;
//
// func setCollectionViewDataSourceDelegate(dataSourceDelegate delegate: protocol<UICollectionViewDelegate,UICollectionViewDataSource>, indexPath: NSIndexPath)
// self.collectionView.dataSource = delegate
// self.collectionView.delegate = delegate
// self.collectionView.indexPath = indexPath
// self.collectionView.tag = indexPath.row
// self.collectionView.reloadData()
//
// MARK: - Collection view data source
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
return 1
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 5
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell: CustomCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CustomCollectionViewCell
//let tableViewCell = tableView!.cellForRowAtIndexPath(NSIndexPath(forItem: collectionView.tag, inSection: 0))
var rect: CGRect?
var label: UILabel = UILabel()
label.font = UIFont(name: "HelveticaNeue-Light", size: 18.0)
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.textAlignment = .Center
switch indexPath.row
case 0:
cell.frame = CGRectMake(0, 0, size!.width * 0.2, size!.height)
rect = cell.bounds
label.frame = rect!
label.text = event!.category
break
case 1:
cell.frame = CGRectMake(size!.width * 0.2, 0, size!.width * 0.3, size!.height)
rect = cell.bounds
label.frame = rect!
label.text = event!.event
break
case 2:
cell.frame = CGRectMake(size!.width * 0.5, 0, size!.width * 0.26, size!.height)
rect = cell.bounds
label.frame = rect!
label.text = event!.location
break
case 3:
cell.frame = CGRectMake(size!.width * 0.76, 0, size!.width * 0.12, size!.height)
rect = cell.bounds
label.frame = rect!
label.text = event!.date
break
case 4:
cell.frame = CGRectMake(size!.width * 0.88, 0, size!.width * 0.12, size!.height)
rect = cell.bounds
label.frame = rect!
label.text = event!.time
break
default:
break
cell.addSubview(label)
cell.layer.borderColor = UIColor.blackColor().CGColor
cell.layer.borderWidth = 0.5
return cell
class func CreateCustomCell() -> CustomTableViewCell
var nibElements: Array = NSBundle.mainBundle().loadNibNamed("CustomTableViewCell", owner: self, options: nil)
var item: AnyObject?
for item in nibElements
if item is UITableViewCell
return item as! CustomTableViewCell
return item as! CustomTableViewCell
CustomCollectionViewCell.swift
class CustomCollectionViewCell: UICollectionViewCell
override init(frame: CGRect)
super.init(frame: frame)
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
override func awakeFromNib()
super.awakeFromNib()
另外,在情节提要中,我向 tableViewCell 添加了一个collectionView,将其连接到出口变量,并将CustomCollectionCell 类设置为情节提要中的collectionCell。
但是当我启动应用程序时,它在 tableViewCellForRowAtIndexPath 中的这一行引发了异常:
2015-07-16 13:29:00.965 CollectionViewInTableViewCell[4241:1005396] 由于未捕获的异常 NSUnknownKeyException 而终止应用程序,原因:[CollectionViewInTableViewCell.CustomTableViewCell 0x126e12440 setValue:forUndefinedKey:]:此类不符合键值编码密钥集合。'
【问题讨论】:
查看我的答案 听到***.com/questions/30159099/… 如何将数据从控制器传递到 customTableViewCell 以将数据输入到 collectionViewCells? 只需将数据属性添加到您的自定义单元格并在控制器中设置它(cellForRowAtIndexPath)。 好的,我会试着告诉你是否有问题。 @mikle94 请参阅cellForAtIndexPath
方法中的示例代码,我将数据传递给单元格,并且在单元格中它将被集合视图使用,例如cell?.folderCount = cardCountArray[indexPath.section]
【参考方案1】:
您的CustomTableViewCell
必须实现UICollectionViewDelegate
和UICollectionViewDataSource
,并且在将其添加到表格视图时,单元格本身必须链接到委托和数据源。
【讨论】:
以上是关于CollectionView 在 tableViewCell 数据显示的主要内容,如果未能解决你的问题,请参考以下文章
如果集合视图已经存在以执行任务,为啥 Xcode 提供 Tableview [重复]
CollectionView 单元格出现在 collectionView 之外。
CollectionView 嵌套在 Collectionview 中
无法在 collectionView 内调用 dequeueReusableCellWithReuseIdentifier(collectionView:collectionViewLayout:si