[英]UICollectionView cells with Images inside UITableView prototype
更新:我解決了我的主要問題,正確的圖像沒有加載,直到在collectionView上滾動。 我在tableView:cellForRowAtIndexPath中添加了一個collectionView.reloadData()。 我還做了一些更改來預加載序列數組,而不是在滾動表時構建它(tableView:cellForRowAtIndexPath)。
如果您有興趣,請將更新添加到GitHub。
https://github.com/Druiced/OpenDeck
一旦我弄清楚如何在返回中放置動態值時防止應用程序崩潰,我將跟進(如果我將其設置為15,則應用程序不會崩潰):
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return count(Array(sequenceArray[collectionView.tag])) / 2
}
原始郵政:請求一些指導。
本教程幫助我意識到這必須與我的DataSource / Delegate有關。 作者用addSubview構建單元格,而不是利用Xcode原型單元,這看起來很酷,所以我試着去做。 http://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell
對我的方法或未能遵循最佳實踐的任何批評都是受歡迎的。
表中的每個單元格都有一個UICollectionView。 “集合視圖”中的每個單元格按照保存的“序列”字符串的順序顯示圖像。 示例:“ADKDQDJDTD”鏈接到AD.png KD.png QD.png JD.png TD.png
我有兩個問題似乎無法解決。
- 當數量由數組長度驅動時,numberOfItemsInSection會變得很糟糕(返回handArray.count / 2)。 如果我放置一個固定的數字,該應用程序將工作,但不是很光滑。
- 當桌子第一次出現時,在我向上和向下滾動桌子之前,不會顯示正確的卡片。 每個CollectionView的數據似乎都是交叉路徑,因為在快速上下滾動時會顯示錯誤的卡片。
我幾乎肯定這與我的數據源設置方式有關。
DeckTableViewController.swift
import UIKit
import Parse
var deviceID: String?
var noRefresh: Bool?
var sequenceArray: Array<Character>?
class DeckTableViewController: UITableViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var handArray: Array<Character>!
var timeLineData:NSMutableArray = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
noRefresh = false
deviceId = UIDevice.currentDevice().identifierForVendor.UUIDString
}
override func viewDidAppear(animated: Bool) {
if noRefresh == false {
loadData()
noRefresh = true
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return timeLineData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:DeckTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! DeckTableViewCell
let deck:PFObject = timeLineData.objectAtIndex(indexPath.row) as! PFObject
cell.collectionView.dataSource = self
cell.collectionView.delegate = self
let sequenceTemp = deck.objectForKey("Sequence") as! String
handArray = Array(sequenceTemp)
cell.sequenceId.setTitle(deck.objectId, forState: UIControlState.Normal)
cell.cardCountLabel.text = "\((count(sequenceTemp)/2))"
// Date to String Stuff
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "(MM-dd) hh:mm:ss"
cell.timeLabel.text = dateFormatter.stringFromDate(deck.updatedAt!)
let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSizeMake(99, 140)
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
cell.collectionView.collectionViewLayout = layout
return cell
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return handArray.count / 2
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:TableCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! TableCollectionViewCell
var bcolor : UIColor = UIColor.orangeColor()
cell.layer.borderColor = bcolor.CGColor
cell.layer.borderWidth = 2
cell.layer.cornerRadius = 3
var firstLetter: Character!
var secondLetter: Character!
//Building card file names from Sequence data
if (indexPath.row * 2) + 1 <= handArray.count {
firstLetter = handArray[indexPath.row * 2]
secondLetter = handArray[indexPath.row * 2 + 1]
let imageNameString = "\(firstLetter)\(secondLetter).png"
let front = UIImage(named: imageNameString)
cell.ImageView.backgroundColor = UIColor.orangeColor()
cell.ImageView.image = front
}
return cell
}
DeckTableViewCell.swift
import UIKit
class DeckTableViewCell: UITableViewCell, UITextViewDelegate {
@IBOutlet var collectionView: UICollectionView!
@IBOutlet var sequenceId: UIButton!
@IBOutlet var timeLabel: UILabel!
@IBOutlet var cardCountLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
TableCollectionViewCell.swift
導入UIKit
class TableCollectionViewCell: UICollectionViewCell {
@IBOutlet var ImageView: UIImageView!
}
對於這個例子,我設置(返回handArray.count / 2)為10並加載3個序列。 頂部中心的數字表示每行的卡數。 請注意,CollectionView不會使用正確的卡進行更新,而是從其他CollectionView中獲取數據。 如果我在這個組合中添加更多序列,當向上和向下滾動時,正確的卡將填充有時,但不可預測。
感謝您的任何建議,我很高興回到繪圖板。 干杯
好吧,讓我們這樣思考,你的DeckTableViewController
充當tableview的數據源, DeckTableViewCell
充當集合視圖的數據源。
考慮到上面的事情,我們創建了一個我不深入的示例項目,我正在給你的例子,就像你經歷的教程一樣
讓我們創建一個帶有單個視圖應用程序的示例項目,並在ViewController
通過以下代碼,我獲取了一個整數數組,其中包含一些值作為在集合視圖中顯示的單元格數。 不要忘記添加tableview並設置其數據源和deleagte。
在我們編寫控制器類之前,我們需要一些類,如自定義tableview cell
和自定義collection view cell
我們首先創建它們
創建一個新文件,它是UICollectionViewCell
的子類,並將其命名為CustomCollectionViewCell
並使用xib
文件。
class CustomCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var aLabel: UILabel! //to show the card number
@IBOutlet weak var imageView: UIImageView! //imageview i am setting it's background color
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
並按照上面的代碼為標簽和圖像視圖創建一個出口。
接下來,創建UITableViewCell
新文件子類,並將其命名為帶有xib file
CustomTableViewCell
。 打開CustomTableViewCell.xib
文件並拖放collection view
並設置它的datasource
並delegate
給cell
而不是控制器。
並為集合視圖創建一個插座,並將其命名為foldersCollectionView
。 傳遞以下代碼
import UIKit
class CustomTableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate {
@IBOutlet weak var foldersCollectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
// fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
var folderCount:Int?
{
didSet(value)
{
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
//configure our collectionview
var aFlowLayout : UICollectionViewFlowLayout = UICollectionViewFlowLayout()
aFlowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
aFlowLayout.itemSize = CGSizeMake(60.0, 90.0)
aFlowLayout.minimumLineSpacing = 10.0
aFlowLayout.minimumInteritemSpacing = 0.0
aFlowLayout.sectionInset = UIEdgeInsetsMake(2, 9, 0, 10)
foldersCollectionView.collectionViewLayout = aFlowLayout
foldersCollectionView.registerClass(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "FOLDER_CELL")
var cNib:UINib? = UINib(nibName: "CustomCollectionViewCell", bundle: nil)
foldersCollectionView.registerNib(cNib, forCellWithReuseIdentifier: "FOLDER_CELL")
foldersCollectionView.frame = self.bounds
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
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
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell :CustomCollectionViewCell? = collectionView.dequeueReusableCellWithReuseIdentifier("FOLDER_CELL", forIndexPath: indexPath) as? CustomCollectionViewCell
//hear u can modify which image to be displayed in the collection view cell
cell?.aLabel.text = "Card:\(indexPath.row)"
return cell!
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return folderCount!
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
}
現在我們將ViewController
類的代碼ViewController
到下面的代碼中
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var cardCountArray:[Int] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
cardCountArray = [5,15,6,12,7,10]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return cardCountArray.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? CustomTableViewCell;
if(cell == nil)
{
cell = CustomTableViewCell.CreateCustomCell()
}
cell?.folderCount = cardCountArray[indexPath.section]
cell?.foldersCollectionView.reloadData()
cell?.clipsToBounds = true
return cell!;
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 100.0
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var headerView:UIView = UIView(frame: CGRectMake(0, 0, tableView.bounds.size.width, 70.0))
var labelTitle:UILabel = UILabel(frame: CGRectMake(0, 0, tableView.bounds.size.width, 35))
var descriptionTitle:UILabel = UILabel(frame: CGRectMake(0, 20,tableView.bounds.size.width , 30))
headerView.addSubview(labelTitle)
headerView.addSubview(descriptionTitle)
labelTitle.text = "TOTAL_CARDS in section:\(section)"
descriptionTitle.text = "This CARD_SECTION contains \(cardCountArray[section]) CARDS"
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50.0
}
}
結果如下
如有任何遺漏,請告訴我
對於你的評論我有一個數組,例如,[“2C3C4C5C6C7C”,“AD2D3D4D5D”,“9H8H7H”]
為此你需要進行以下修改
//for first row u get like this
//the string for the row is 2C3C4C5C6C7C
//stringForCell = "2C3C4C5C6C7C"
//2C
//3C
//4C
//5C
//6C
//7C
//for other cells u can get like below
//the string for the row is AD2D3D4D5D
//stringForCell = "AD2D3D4D5D"
//AD
//2D
//3D
//4D
//5D
//the string for the row is 9H8H7H
//stringForCell = "9H8H7H"
//9H
//8H
//7H
//in controller controller class define array of string
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var cardCountArray:[Int] = []
var stringArray : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
stringArray = ["2C3C4C5C6C7C", "AD2D3D4D5D", "9H8H7H"]
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
// return cardCountArray.count
return stringArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? CustomTableViewCell;
if(cell == nil)
{
cell = CustomTableViewCell.CreateCustomCell()
}
//cell?.folderCount = cardCountArray[indexPath.section]
cell?.stringForCell = stringArray[indexPath.section];
cell?.foldersCollectionView.reloadData()
cell?.clipsToBounds = true
return cell!;
}
//in custom tableview cell add a string variable
class CustomTableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate {
@IBOutlet weak var foldersCollectionView: UICollectionView!
var stringForCell:String = "" //add the string to hold the string
//rest of the code
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell :CustomCollectionViewCell? = collectionView.dequeueReusableCellWithReuseIdentifier("FOLDER_CELL", forIndexPath: indexPath) as? CustomCollectionViewCell
var str:NSString = stringForCell
var length = str.length
var totalLlength:Int = length/2
var indexStart = indexPath.row * (2);
var aRange = NSMakeRange(indexStart, 2)
var cardString:NSString = str.substringWithRange(aRange)
println(cardString)
cell?.aLabel.text = "Card: \(cardString)"
return cell!
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
println("the string for the row is \(stringForCell)")
var str:NSString = stringForCell
var length:Int = str.length
return length / 2
//return folderCount!
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
我寫了一篇關於如何在自定義表視圖單元格中添加集合視圖的詳細帖子聽到希望這給出了比這篇文章更詳細的解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.