在UITableView原型

时间:2015-05-11 03:10:12

标签: ios iphone uitableview swift uicollectionview

更新:我解决了我的主要问题,正确的图像没有加载,直到在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

enter image description here

我有两个问题似乎无法解决。

  
      
  • 当数组长度驱动卡数时,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中获取数据。如果我在这个组合中添加更多序列,当向上和向下滚动时,正确的卡将填充有时,但不可预测。

enter image description here

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

1 个答案:

答案 0 :(得分:7)

好的,让我们这样思考,您的DeckTableViewController充当tableview的数据源,DeckTableViewCell充当集合视图的数据源。

考虑到上述事情,我们创建了一个示例项目 我没有深入,我正在给你的例子,因为你经历了

让我们在ViewController中使用单一视图应用创建示例项目 通过下面的代码,我获取了一个整数数组,其中包含一些值,表示在集合视图中显示多少个单元格。不要忘记添加tableview并设置其数据源并删除。

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

创建一个新文件,该文件是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()

    }
}

并为标签和图片视图创建一个出口,如上面的代码所示。

接下来,创建UITableViewCell的新文件子类,并将其命名为CustomTableViewCell xib file。打开CustomTableViewCell.xib文件并拖放collection view并将其datasourcedelegate设置为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类 现在刚刚通过以下代码

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

结果将如下所示

enter image description here

如果有任何遗漏,请告诉我

您的评论我有一个数组,例如,[&#34; 2C3C4C5C6C7C&#34;,&#34; AD2D3D4D5D&#34;,&#34; 9H8H7H&#34;] < / p>

为此你需要进行以下修改

//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的详细帖子。听到希望这给出了比这篇文章更详细的解释。