如果您有兴趣,请将更新添加到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 gets whacky when the number of cards is driven by the array length (return handArray.count / 2). If I place a fixed number the app will work, but not very slick.
- When the table first comes up, the correct cards do not display until I scroll up and down the table. It also appears the data for each CollectionView is crossing paths as the wrong cards show up when scrolling up and down rapidly.
我几乎肯定这与我的数据源设置方式有关.
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单元格和自定义集合视图单元格,我们首先创建它们
创建一个新文件,它是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文件的CustomTableViewCell.打开CustomTableViewCell.xib文件并拖放集合视图并设置它的数据源并委托给单元而不是控制器.
并为集合视图创建一个插座,并将其命名为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类
现在刚刚通过以下代码
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 }
我写了一篇关于how to add collection view inside custom table view cell的详细帖子听到希望这给出了比这篇文章更详细的解释.