2016-11-02 2 views
0

Я пытаюсь показать мои данные, как это image.Swift: как отображать проанализированные данные JSON в CollectionView внутри TableView?

Моя проблема заключается в том, что данные, отображаемые в строках таблицы просмотреть все то же самое, в то время как он должен отображать все данные массива.

Это код, который я использовал для отображения CollectionView внутри Tableview:

var onlineNews = ["local", "Economy", "Variety", "international", "sport"] 

var storedOffsets = [Int: CGFloat]() 

var tableIndexPath: IndexPath! 

@IBOutlet var listTableView: UITableView! 

var tableIndex: Int = 0 

var categoryResults = [JSON]() { 
    didSet { 
     listTableView.reloadData() 
    } 
} 

let requestManager = RequestManager() 


override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    for i in onlineNews { 
     requestManager.categoryList(sectionName: i) 
    } 
} 


func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return onlineNews.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! NewsTableViewCell 

    tableIndex = indexPath.row 

    return cell 
} 

func tableView(_ tableView: UITableView, 
       willDisplay cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 
     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: (indexPath as NSIndexPath).row) 
     tableViewCell.collectionViewOffset = storedOffsets[(indexPath as NSIndexPath).row] ?? 0 
} 

func tableView(_ tableView: UITableView, 
       didEndDisplaying cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 

     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     storedOffsets[(indexPath as NSIndexPath).row] = tableViewCell.collectionViewOffset 
} 

func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 1 
} 

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

    return categoryResults.count 
} 

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

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


    cell.contentType.text = categoryResults[indexPath.row]["ContentType"].stringValue **// This is where I get the same values for all table view rows** 
    cell.sectionName.text = onlineNews[tableIndex] 


    return cell 
} 

Я уверен, что кто-то может помочь мне абсолютно с этим, как я знаю, что он занимает лишь небольшую подправить, чтобы заставить его работать , но не знаю где.

Update:

Я последовал путь, который я считаю, должен работать, который должен объявить массив JSON, чтобы быть, как это [[JSON]], а затем использовать categoryResults [collection.tag] [ indexPath.item] ["ContentType"]. stringValue, чтобы получить значение. Однако это дает мне сообщение «индекс за пределами диапазона». У вас есть какая-то подсказка, как я могу решить проблему?

var onlineNews = ["local", "Economy", "Variety", "international", "sport"] 

var storedOffsets = [Int: CGFloat]() 

@IBOutlet var listTableView: UITableView! 

var tableIndex: Int = 0 

var categoryResults = [[JSON]]() { // updated 
    didSet { 
     listTableView.reloadData() 
    } 
} 

let requestManager = RequestManager() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    requestManager.resetCategory() 

    updateSearchResults() 

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateSearchResults), name: NSNotification.Name(rawValue: "categoryResultsUpdated"), object: nil) 


} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    for i in 0..<onlineNews.count { 
     requestManager.categoryList(sectionName: onlineNews[i]) 


    } 

} 

func updateSearchResults() { 
    categoryResults = [requestManager.categoryResults] // updated 
} 

func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return onlineNews.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! NewsTableViewCell 

    tableIndex = indexPath.row 

    return cell 
} 

func tableView(_ tableView: UITableView, 
       willDisplay cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 
     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: (indexPath as NSIndexPath).row) 
     tableViewCell.collectionViewOffset = storedOffsets[(indexPath as NSIndexPath).row] ?? 0 

} 

func tableView(_ tableView: UITableView, 
       didEndDisplaying cell: UITableViewCell, 
       forRowAt indexPath: IndexPath) { 

     guard let tableViewCell = cell as? NewsTableViewCell else { return } 

     storedOffsets[(indexPath as NSIndexPath).row] = tableViewCell.collectionViewOffset 


} 

func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 1 
} 


func collectionView(_ collectionView: UICollectionView, 
        numberOfItemsInSection section: Int) -> Int { 
    return categoryResults[collectionView.tag].count // updated 
} 


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

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


    cell.contentType.text = categoryResults[collectionView.tag][indexPath.row]["ContentType"].stringValue // updated 



    return cell 
} 

Это содержание класса RequestManager (где я называю API):

var categoryResults = [JSON]() 

func categoryList(sectionName: String) { 

    let url = "http://mobile.example.com/api/Content?MobileRequest=GetCategoryNews&PageNo=1&RowsPerPage=10&Category=\(sectionName)&IssueID=0&Type=online" 
    print("this is the url \(url)") 

    Alamofire.request(url, method: .get).responseJSON{ response in 
     if let results = response.result.value as? [String:AnyObject] { 
      let items = JSON(results["Data"]?["OnlineCategoryNews"]! as Any).arrayValue 

      self.categoryResults += items 

      NotificationCenter.default.post(name: NSNotification.Name(rawValue: "categoryResultsUpdated"), object: nil) 

     } 

    } 

} 

func resetCategory() { 
    categoryResults = [] 
} 

deinit { 
    NotificationCenter.default.removeObserver(self) 
} 

Update 2:

А вот способ, где collectionView.tag назначается. Это добавляется к классу tableViewCell:

func setCollectionViewDataSourceDelegate 
    <D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>> 
    (dataSourceDelegate: D, forRow row: Int) { 

    collectionView.delegate = dataSourceDelegate 
    collectionView.dataSource = dataSourceDelegate 
    collectionView.tag = row 
    collectionView.bounds.size.width = self.bounds.size.width 
    collectionView.reloadData() 



} 

ответ

0

Методы делегатов коллекции не знают контекста их коллекции. Вы должны рассчитать onlineNews-индекс в зависимости от экземпляра collectionView, а не с помощью indexPath.row, который является внутренним индексом просмотра коллекции.

Редактировать: лучший вариант (чтобы избежать проблем с прокруткой и компоновкой) заключается в использовании единого представления коллекции, где ячейки сгруппированы в строки. Если вы не хотите, чтобы менеджер компоновки, вы можете достичь такого макета, добавляя небольшие, но очень широкие взгляды разделителей между секциями

edit2:

cell.contentType.text = categoryResults[indexPath.row]["ContentType"].stringValue 

использует локальный indexPath этой точки зрения сбора. Вы можете назначить тег tableViewCell.collectionView со значением желаемого индекса категории результатов. Тогда вы можете использовать этот тег как в categoryResults[collectionView.tag]

+0

Благодарим за ответ. Не могли бы вы объяснить, как и где этот индекс можно использовать для отображения результата? Я пробовал различные методы, такие как использование collectionView.tag вместо indexPath.row, и он не работал, но не уверен, как индекс может быть назначен для отображения результата JSON. Мне нужно еще кое-что объяснить. – Maryoomi1

+0

Я имею в виду, мне нужно объяснение того, как индекс можно рассчитать, как вы упомянули, чтобы помочь получить результат JSON. – Maryoomi1

+0

Обновлено мой ответ – user1232690

Смежные вопросы