TableviewCell 中的 CollectionView :使用 Alamofire 和 SwiftyJSON 和 MVC 模型显示数据

Posted

技术标签:

【中文标题】TableviewCell 中的 CollectionView :使用 Alamofire 和 SwiftyJSON 和 MVC 模型显示数据【英文标题】:CollectionView in TableviewCell : Display data using Alamofire and SwiftyJSON with MVC model 【发布时间】:2019-01-18 14:50:14 【问题描述】:

我在 Tableviewcell 中有一个 Collectionview。我使用 Alamofire 和 SwiftJSON 下载数据并存储在我的模型项目中。我有 2 个模型文件,一个用于 tableview,一个用于 collectionview

Tableview 模型项目:

class Matchs 
    var matchTime : String
    var matchMbs : Int
    var matchLeague : String
    var matchCode : Int
    var matchHomeTeam : String
    var matchAwayTeam : String

    init(time : String, mbs : Int, league : String, code : Int, homeTeam : String, awayTeam : String ) 

        matchTime = time
        matchMbs = mbs
        matchLeague = league
        matchCode = code
        matchHomeTeam = homeTeam
        matchAwayTeam = awayTeam

    

Collectionview 的模型项目:

class MatchsOdds 

    var homeWin : Double
    var awayWin : Double
    var draw : Double
    var under : Double
    var over : Double
    var oddResult = ["1","0","2","Under","Over"]

    init(homeWin: Double, awayWin : Double, draw : Double, under : Double, over : Double) 
        self.homeWin = homeWin
        self.awayWin = awayWin
        self.draw = draw
        self.under = under
        self.over = over
    


这里是 Viewcontroller 代码:

class MainViewController: UIViewController 

  @IBOutlet weak var tableview: UITableView!



    let MATCH_URL = "somelink"
    var match : [Matchs] = []
    var matchOdd : [MatchsOdds] = []


    @IBOutlet weak var totalMatchLabel: UILabel!

    @IBOutlet weak var totalOddsLabel: UILabel!

    fileprivate func getMatchData(url:String) 

        Alamofire.request(url).responseJSON 
            response in
                if response.result.isSuccess 
                    print("I got the match data")
                    let matchJSON : JSON = JSON(response.result.value!)
                    self.getMatch(json: matchJSON)

                else 
                    print("Match Unavailable")
                

          self.tableview.reloadData()
      

    


    fileprivate func getMatch(json: JSON) 

      if let matchs = json["data"]["b"]["f"]["list"].array 

        matchs.forEach  (arg0) in

          let events = arg0
          let tournamentName = events["tournamentName"].stringValue
          let homeTeam = events["homeTeam"].stringValue
          let mbs = events["mbs"].intValue
          let matchCode = events["matchCode"].intValue
          let matchTime : String = events["eventHour"].stringValue
          let awayTeam = events["awayTeam"].stringValue
          let matchTimeFirst5 = matchTime.prefix(5)

          let allMatch = Matchs(time: String(matchTimeFirst5), mbs: mbs, league: tournamentName, code: matchCode, homeTeam: homeTeam, awayTeam: awayTeam)


          let homeWin = events["oddList"][0]["v"].doubleValue
          let draw = events["oddList"][1]["v"].doubleValue
          let awaywin = events["oddList"][2]["v"].doubleValue
          let under = events["oddList"][3]["v"].doubleValue
          let over = events["oddList"][4]["v"].doubleValue



          let fiveOdds = MatchsOdds(homeWin: homeWin, awayWin: awaywin, draw: draw, under: under, over: over)
          match.append(allMatch)
          matchOdd.append(fiveOdds)

        

    

  


    override func viewDidLoad() 
        super.viewDidLoad()

        getMatchData(url: MATCH_URL)
    
    override func viewDidAppear(_ animated: Bool) 


        


extension MainViewController: UITableViewDelegate,UITableViewDataSource 
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return match.count
  

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let matcCell = match[indexPath.row]

    let cell = tableView.dequeueReusableCell(withIdentifier: "oddsCell") as! OddsTableViewCell

    tableView.separatorStyle = .none
    cell.matchToMatch(matcs: matcCell)
    tableview.allowsSelection = false
    cell.collectionview.tag = indexPath.row
    cell.collectionview.reloadData()
    cell.matchOddCV = matchOdd
    return cell
  

从这里没问题。我将数据写入 Tableviewcell 标签。但是当我尝试将 matchOdds 数据添加到 Collectionview 单元格标签时。我只得到了像这样重复的第一个数据:

这是 Tableviewcell 的代码:

class OddsTableViewCell: UITableViewCell 

    @IBOutlet weak var reloadButton: RoundedButton!
    @IBAction func reloadBottonPressed() 
        print("reloadDataPressed")

    
    var matchOddCV : [MatchsOdds]!
    @IBOutlet weak var collectionview: UICollectionView!
    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var mbsLabel: UILabel! 
        didSet
            mbsLabel.layer.cornerRadius = 5
            mbsLabel.layer.masksToBounds = true
        
    

    @IBOutlet weak var leageLabel: UILabel!

    @IBOutlet weak var matchCodeLabel: UILabel!
    @IBOutlet weak var homeVsAwayLabel: UILabel!



    override func awakeFromNib() 
        super.awakeFromNib()
        collectionview.dataSource = self
        collectionview.delegate = self

    

    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

    

    func matchToMatch (matcs : Matchs) 
        timeLabel.text = matcs.matchTime
        mbsLabel.text = String(matcs.matchMbs)
        leageLabel.text = matcs.matchLeague
        matchCodeLabel.text = String(matcs.matchCode)
        homeVsAwayLabel.text = "\(matcs.matchHomeTeam) - \(matcs.matchAwayTeam)"
    




extension OddsTableViewCell: UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        return CGSize(width: collectionView.bounds.width/5, height: collectionView.bounds.height)
    


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 5
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "oddsCollectionViewCell", for: indexPath) as! OddsCollectionViewCell

        let matchCell = matchOddCV[indexPath.row]

        if indexPath.row == 0 
                  cell.matchResultLabel.text = matchCell.oddResult[0]
                  cell.matchOddsLabel.text = String(matchCell.homeWin)

                else if indexPath.row == 1
                  cell.matchResultLabel.text = matchCell.oddResult[1]
                  cell.matchOddsLabel.text = String(matchCell.draw)

                else if indexPath.row == 2 
                  cell.matchResultLabel.text = matchCell.oddResult[2]
                  cell.matchOddsLabel.text = String(matchCell.awayWin)

                else if indexPath.row == 3 
                  cell.matchResultLabel.text = matchCell.oddResult[3]
                  cell.matchOddsLabel.text = String(matchCell.under)

                else if indexPath.row == 4 
                  cell.matchResultLabel.text = matchCell.oddResult[4]
                  cell.matchOddsLabel.text = String(matchCell.over)

                

        cell.matchOddsLabel.layer.borderWidth = 0.5
        cell.matchOddsLabel.layer.borderColor = UIColor.lightGray.cgColor
        cell.matchResultLabel.layer.borderWidth = 0.5
        cell.matchResultLabel.layer.borderColor = UIColor.lightGray.cgColor
        return cell
    


Collectionviewcell 代码:

class OddsCollectionViewCell: UICollectionViewCell 

    @IBOutlet weak var matchResultLabel: UILabel!
    @IBOutlet weak var matchOddsLabel: UILabel!

【问题讨论】:

【参考方案1】:

根据表的cellForRowAt

cell.collectionview.reloadData()
cell.matchOddCV = matchOdd

您为所有表格单元格中的所有集合分配相同的数组,您需要在每个 Matchs 对象中创建一个数组属性并执行

let matcCell = match[indexPath.row]
cell.matchOddCV = matcCell.odds // create odds array and assign data for each object
cell.collectionview.reloadData()

【讨论】:

另外,我认为 TableView 中的 reloadData() cellForRowAt 没有任何作用。重新加载需要作为 CollectionView 的一部分发生 @dst3p 因为 dequeuing 需要它,如果你只设置数组,你会得到一个包含内容的 dequeued 单元格,但集合显示旧数据 非常感谢它解决了我的问题。此外,当我在 Tableviewcell 中使用 let matchCell = matchOddCV[indexPath.row] 时,我的 swift 索引超出了范围。我没有使用它,而是使用 let matchCell = matchOddCV[0] 这解决了我的问题。 确保你在numberOfRowsAt中返回match.count【参考方案2】:

如我所见,在设置新列表 matchOddCV 之前,您正在重新加载 collectionview

所以你应该这样做:

// assign the new list
 cell.matchOddCV = matchOdd
// reload colllectionview
 cell.collectionview.reloadData()

【讨论】:

以上是关于TableviewCell 中的 CollectionView :使用 Alamofire 和 SwiftyJSON 和 MVC 模型显示数据的主要内容,如果未能解决你的问题,请参考以下文章

tableviewcell 中的图像不会立即出现

我的 UITapGestureRecognizer 影响 TableViewCell 中的所有元素

如何将 viewController 中的数据分配给 tableViewCell 标签?

如何更改特定 TableViewCell 中的按钮颜色

按下 tableViewCell 中的按钮时打开一个新的 VC

didSelectRowAtIndexPath 中的 tableViewCell 附件类型问题