在UITableView原型中包含图像的UICollectionView单元格

更新:我解决了我的主要问题正确的图像不加载,直到滚动collectionView。 我添加了一个collectionView.reloadData()到tableView:cellForRowAtIndexPath。 我也做了一些修改来预加载序列数组,而不是在滚动表(tableView:cellForRowAtIndexPath)的时候创build它。

如果您有兴趣,可以将更新添加到GitHub。
https://github.com/Druiced/OpenDeck

一旦我找出如何防止应用程序崩溃,当dynamic值被放置在返回(如果我将其设置为15,应用程序不会崩溃),我会后续:

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return count(Array(sequenceArray[collectionView.tag])) / 2 } 

原来的post:请求一些指导。

本教程帮助我意识到这必须与我的DataSource / Delegate有关。 作者使用addSubview构build单元格,而不是利用Xcode原型单元格,这似乎是一件很酷的事情,所以我正在尝试这样做。 http://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell

任何批评我的做法或不遵循最佳做法是值得欢迎的。

表中的每个单元格都有一个UICollectionView。 集合视图中的每个单元格按保存的“序列”string的顺序显示图像。 例如:“ADKDQDJDTD”链接到AD.png KD.png QD.png JD.png TD.png

在这里输入图像说明

我有两个问题,我似乎无法通过。

  • numberOfItemsInSection当卡数由数组长度驱动(返回handArray.count / 2)时会变得怪异。 如果我放置一个固定的号码应用程序将工作,但不是很光滑。
  • 桌子第一次出现时,正确的牌不会显示,直到我上下滚动桌子。 它也显示每个CollectionView的数据是交叉的path,因为当快速上下滚动时显示错误的卡片。

我几乎肯定这与我的数据源是如何设置的。

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中获取数据。 如果我为这个混合添加更多的序列,当上下滚动时,正确的卡片将填充有时,但不可预知。

在这里输入图像说明

感谢您的任何build议,我很高兴回到绘图板。 干杯

好吧,让我们这样想, DeckTableViewController充当tableview的数据源, DeckTableViewCell充当collection数据源的视图。

考虑到上面的事情,我们创build一个示例项目,我不深入,我正在给你的例子像教程,因为你经历

让我们创build一个示例项目与单个视图应用程序,并在ViewController通过下面的代码,我拿了一个整数数组,其中包含一些值作为多less个单元格出现在集合视图。 不要忘记添加tableview并设置其数据源和删除。

在我们编写控制器类之前,我们需要一些像自定义tableview cell和自定义collection view cell这样的类,我们首先创build它们

创build一个新文件,它是UICollectionViewCell的子类,并将其命名为CustomCollectionViewCellxib文件。

 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() } } 

并在上面的代码中创build标签和图像视图的出口。

接下来,创buildUITableViewCell新文件子类,并用xib file其命名为CustomTableViewCell 。 打开CustomTableViewCell.xib文件并拖放collection view ,并将其datasourcedelegatecell而不是控制器。

并为集合视图创build一个出口并将其命名为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 }