arrays - Swift:如何在 TableView 内的 CollectionView 中显示解析的 JSON 数据?

标签 arrays json swift uitableview uicollectionview

我正在尝试将我的数据显示为 image.

我的问题是 TableView 行内显示的数据都是相同的,而它应该显示数组的所有数据。

这是我用来在 tableView 中显示 collectionView 的代码:

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
}

我确信有人绝对可以帮助我解决这个问题,因为我知道只需要进行一些小的调整即可使其工作,但不确定在哪里。

更新:

我遵循了一种我认为应该可行的方法,即将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)
}

更新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()



}

最佳答案

Collection View 委托(delegate)方法不知道其 Collection View 的上下文。您应该根据collectionView实例计算onlineNews索引,而不是使用indexPath.row,它是内部 Collection View 索引路径。

编辑:更好的选择(避免滚动和布局问题)是使用单个 Collection View ,其中单元格按行分组。如果您不想制作布局管理器,您可以通过在部分之间添加小但非常宽的分隔符 View 来实现此类布局

编辑2:

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

使用此 Collection View 的本地索引路径。您可以将标记分配给 tableViewCell.collectionView 并指定所需的categoryResults 索引值。然后您可以使用此标签,如categoryResults[collectionView.tag]

关于arrays - Swift:如何在 TableView 内的 CollectionView 中显示解析的 JSON 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40379059/

相关文章:

c++ - 为什么在 C++ 中删除动态分配的数组后不能重用它的名称?

javascript - 在 Javascript 中将键值对的 JSON 数组转换为 JSON 字符串数组

c# - 如何将二维 JSON 数组发布到 Web 服务

objective-c - 如何将 JSON 字符串转换为 NSArray?

c# - JSON 与 XML 基准? (C#)

ios - 对象 [2866] : pthread_rwlock_rdlock failed (11)

swift - 在 swift 3 中使用未解析的标识符 'println'

c - 将txt文件放入数组中从第12个元素开始

arrays - 在 ruby​​ 中拆分字符串数组的最佳方法?

ios - Swift 2.0/UITableViewCell - 滚动时无法在顶部位置的单元格中发生操作