【问题标题】:Populate UITableview with Array from Rest API in Swift在 Swift 中使用来自 Rest API 的数组填充 UITableview
【发布时间】:2016-11-18 08:25:18
【问题描述】:

在我的 mainTableView 控制器中,我可以在控制台中打印 API 结果,但我不知道如何将它们设置为在我的 tableview 的单元格中可见

import UIKit
//from: https://github.com/Ramotion/folding-cell
class MainTableViewController: UITableViewController {

let kCloseCellHeight: CGFloat = 179
let kOpenCellHeight: CGFloat = 488

let kRowsCount = 100

var cellHeights = [CGFloat]()
var restApi = RestApiManager()
var items: NSDictionary = [:]


override func viewDidLoad() {
    super.viewDidLoad()

    restApi.makeCall() { responseObject, error in
        // use responseObject and error here
        //  self.json = JSON(responseObject!)

        print("print the json data from api ")
        self.items = NSDictionary(dictionary: responseObject!)
        self.tableView.reloadData()
        print(responseObject!.count)
       // print(self.items)
        let resultList = self.items["result"] as! [[String: 
 AnyObject]]
        print(resultList[5])
    }

    createCellHeightsArray()
    self.tableView.backgroundColor = UIColor(patternImage: 
  UIImage(named: "background")!)


}

// MARK: configure
func createCellHeightsArray() {
    for _ in 0...kRowsCount {
        cellHeights.append(kCloseCellHeight)
    }
}

// MARK: - Table view data source

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10
}

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    guard case let cell as DemoCell = cell else {
        return
    }

    cell.backgroundColor = UIColor.clearColor()

    if cellHeights[indexPath.row] == kCloseCellHeight {
        cell.selectedAnimation(false, animated: false, completion:nil)
    } else {
        cell.selectedAnimation(true, animated: false, completion: nil)
    }

    cell.number = indexPath.row
}


// with as! the cell is set to the custom cell class: DemoCell
// afterwards all data can be loaded in this method
override func tableView(tableView: UITableView, cellForRowAtIndexPath    
indexPath: NSIndexPath) -> UITableViewCell {
    let cell = 
tableView.dequeueReusableCellWithIdentifier("FoldingCell", 
forIndexPath: indexPath) as! DemoCell

//TODO: set all custom cell properties here (retrieve JSON and set in 
cell), use indexPath.row as arraypointer

//    let resultList = self.items["result"] as! [[String: AnyObject]]
 //   let itemForThisRow = resultList[indexPath.row]
//  cell.schoolIntroText.text = itemForThisRow["name"] as! String

    cell.schoolIntroText.text = "We from xx University..."
    return cell
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return cellHeights[indexPath.row]
}

// MARK: Table vie delegate

override func tableView(tableView: UITableView, 
didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let cell = tableView.cellForRowAtIndexPath(indexPath) as! 
FoldingCell

    if cell.isAnimating() {
        return
    }

    var duration = 0.0
    if cellHeights[indexPath.row] == kCloseCellHeight { // open cell
        cellHeights[indexPath.row] = kOpenCellHeight
        cell.selectedAnimation(true, animated: true, completion: nil)
        duration = 0.5
    } else {// close cell
        cellHeights[indexPath.row] = kCloseCellHeight
        cell.selectedAnimation(false, animated: true, completion: 
nil)
        duration = 0.8
    }

    UIView.animateWithDuration(duration, delay: 0, options: 
.CurveEaseOut, animations: { () -> Void in
        tableView.beginUpdates()
        tableView.endUpdates()
        }, completion: nil)


}    
}

我在 JSON 中得到这个结果,这是正确的

{
 result =     (
            {
        city = Perth;
        "cou_id" = AU;
        environment = R;
        image = "-";
        name = "Phoenix English";
        rating = 0;
        "sco_id" = 2;
        "sco_type" = LS;
    },
            {
        city = "Perth ";
        "cou_id" = AU;
        environment = L;
        image = "-";
        name = "Milner college";
        rating = 0;
        "sco_id" = 3;
        "sco_type" = LS;
    },

如何设置这些值并在此处设置它们?

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("FoldingCell", forIndexPath: indexPath) as! DemoCell
    //TODO: set all custom cell properties here (retrieve JSON and set in cell), use indexPath.row as arraypointer

    cell.schoolIntroText.text = "We from xx University..."
    return cell
}

我不知道如何从这个 JSON 输出构造一个数组,以及如何访问这些似乎嵌套在多个维度中的字段, 作为菜鸟,感谢任何输入。

从类 restApi 中添加:

// working method for calling api
func makeCall(completionHandler: (NSDictionary?, NSError?) -> ()) {

    Alamofire.request(
        .GET,
        baseURL+schools+nonAcademicParameter,
        headers: accessToken
        )
        .responseJSON { response in
            switch response.result {
            case .Success(let value):
                completionHandler(value as? NSDictionary, nil)
            case .Failure(let error):
                completionHandler(nil, error)
            }
    }
}

【问题讨论】:

    标签: json swift uitableview rest alamofire


    【解决方案1】:

    在您的 TODO 点:

    let resultList = self.items["result"] as! [[String: AnyObject]]
    let itemForThisRow = resultList[indexPath.row]
    cell.cityLabel.text = itemForThisRow["city"] as! String
    cell.nameLabel.text = itemForThisRow["name"] as! String
    ...
    

    为了让处理 json 更容易,请尝试SwiftyJSON

    【讨论】:

    • 谢谢,但是 let resultList = self.items["result"] 一行! [[String: AnyObject]] 给出错误说明:线程 1:EXEC_BAD_INSTRUCTION.... 并在日志中:致命错误:在展开可选值时意外发现 nil。任何想法为什么会这样?
    • 您的 json 是否有名为“result”的顶级元素?
    • 我不知道顶级元素到底是什么。从我的 JSON 响应中,“结果”只是在开头一次:result = ({array 1},{array 2},etc.. 感谢您的帮助
    • 如果我在 viewDidLoad 中运行这段代码 sn-p,它可以工作并且数据被正确解析。在我看来,单元格希望在返回结果调用之前加载它。这可能是问题吗?我编辑了我的问题并上传了整个 UItableview 类。
    【解决方案2】:

    我现在想通了。内部resultList数组的大小需要传入numberOfRowsSelection。然后动态加载单元格。

    override func tableView(tableView: UITableView, numberOfRowsInSection    
    section: Int) -> Int {
        print("size of self.resultlist.count: ")
        print(self.resultList.count)
    
        //size of the inner array with all the acutal values have to be 0 
    at the beginning. when the async call comes back with the whole 
    result, it will be updated. so it has to be set to the size of the 
    array
    
    //http://www.unknownerror.org/opensource/Alamofire/Alamofire/q/stackoverflow/29728221/uitableview-got-rendered-before-data-from-api-returned-using-swiftyjson-and-alam
    
        return self.resultList.count
    }
    

    【讨论】:

    • 您遇到过自动布局问题吗?我正在使用带有当前 git 版本的 swift3.0。我从 APi 获取数据,但是当我改变任何东西时,创建新的 iboutlet 并连接。屏幕消失。但是当我点击它显示折叠单元格。 :(
    猜你喜欢
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 2016-07-24
    相关资源
    最近更新 更多