将数据从一个tableview传递到另一个tableview

时间:2015-08-24 14:07:18

标签: ios swift uitableview tableviewcell

在我的应用程序中,我有两个表视图。第一个表视图具有一定数量的单元格。 这些细胞将永远是相同的,永远不会改变。

见下文:

enter image description here

上面的表视图将始终具有3个单元格,而且永远不会更多。 在我的服务器上,我有我的API,其中包含每个单元格的路由。

例如:

GET - myAPI / game

GET - myAPI / book

GET - myAPI / travel

每条路线发回不同的数据。

我想要做的是,当用户点击表格视图单元格时,它会将它们带到新的表格视图,其中的单元格包含来自API的响应

目前我的2ND表视图为空,见下文:

enter image description here

这是我到目前为止所尝试的内容:

 import UIKit

 class SectorListTableViewController: UITableViewController {


struct WeatherSummary {
    var id: String
}

var testArray = NSArray()
var manuArray = NSArray()

// Array of sector within our company
var selectSector: [String] = ["Game", "Book","Travel"]

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.rowHeight = 80.0




    var weatherArray = [WeatherSummary]()
    var request = NSMutableURLRequest(URL: NSURL(string: "myAPI")!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "GET"
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    //var params = ["email":"\(emailAdd)", "password":"\(pass)"] as Dictionary<String, String>

    var err: NSError?
    //request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        println("Response: \(response)")
        var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Body: \(strData)")
        var err: NSError?
        var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSArray

        UIApplication.sharedApplication().networkActivityIndicatorVisible = true

        // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
        if(err != nil) {

            println(err!.localizedDescription)
            let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("Error could not parse JSON: '\(jsonStr)'")

        }
        else {

            UIApplication.sharedApplication().networkActivityIndicatorVisible = false
            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            var newWeather = WeatherSummary(id:"")

            if let parseJSON = json {

                for weather in parseJSON {

                    if let id = weather["employeeName"] as? String{
                        println(" LOOK HERE \(id)")
                        newWeather.id = id
                    }
                }

                weatherArray.append(newWeather)

                self.testArray = parseJSON


            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
                println("Error could not parse JSON: \(jsonStr)")

            }


        }

    })



    task.resume()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()



}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    return self.selectSector.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("sectorList", forIndexPath: indexPath) as! UITableViewCell

    // Configure the cell...

    if selectSector.count > 0 {

        cell.textLabel?.text = selectSector[indexPath.row]
    }

    return cell
}


/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return NO if you do not want the specified item to be editable.
    return true
}
*/

/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }    
}
*/

/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

}
*/

/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return NO if you do not want the item to be re-orderable.
    return true
}
*/


// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.

    if let destination = segue.destinationViewController as? BioListTableViewController {
      let indexPath = self.tableView.indexPathForSelectedRow()

        if let row:Int = indexPath?.row {


        destination.bioArray = testArray




            }
          }
        }
      }

BIO LIST VIEW CONTROLLER CLASS CODE:

import UIKit

 struct Note {

var name:String
var job:String
}


 class BioListTableViewController: UITableViewController {

private var notes = Array<Note>()

var bioArray = NSArray()
var name = String()

 var weather = NSArray()

override func viewDidLoad() {
    super.viewDidLoad()

    println("THIS IS BIO ARRAY COUNT\(bioArray.count)")
     //var weather:WeatherSummary?
    var newItem:Note = Note(name: "", job: "")

    for x in bioArray {
        if let id = x["employeeName"] as? String{
            newItem.name = id
        }
    }

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    return self.bioArray.count ?? 0
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("bioCell", forIndexPath: indexPath) as! UITableViewCell

    // Configure the cell...

   // cell.textLabel?.text = "test"

    let weatherSummary: AnyObject = bioArray[indexPath.row]

    if let id = weatherSummary["employeeName"] as? String //Dont know the exact syntax.
    {
        cell.textLabel?.text = id

    }

    if let job = weatherSummary["jobTitle"] as? String {
        cell.detailTextLabel?.text = job

    }


    return cell
  }

 }

更新

这是从testArray返回的内容。

enter image description here

2 个答案:

答案 0 :(得分:2)

您无法让API调用在单元格选择上工作的原因很简单。

这些是异步调用。这意味着他们将在某个时刻返回,但不一定很快。事实上,您现在拥有的设计也很糟糕,因为如果您的互联网连接速度很慢,可能需要很长时间才能加载API。

这是你应该做的。

$ gulp php-serve [07:30:09] Requiring external module babel-core/register [07:30:11] Using gulpfile ~\...\gulpfile.babel.js [07:30:11] Starting 'styles'... [07:30:12] Starting 'fonts'... [07:30:12] Finished 'styles' after 1.08 s [07:30:12] Finished 'fonts' after 306 ms [07:30:12] Starting 'php-serve'... [07:30:12] Finished 'php-serve' after 183 ms [BS] Access URLs: ---------------------------------- Local: http://localhost:9000 External: http://x.x.x.x:9000 ---------------------------------- UI: http://localhost:3001 UI External: http://x.x.x.x:3001 ---------------------------------- [BS] Serving files from: .tmp [BS] Serving files from: app C:\...\node_modules\http-proxy\lib\http-proxy\index.js:119 throw err; ^ Error: connect ECONNREFUSED at exports._errnoException (util.js:746:11) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1010:19) 创建一个变量,该变量将标识需要调用哪个API(可能值得将其设为BioListTableViewController):

enum

您现在要做的是将API调用逻辑移到enum NeededAPI { case Game case Book case Travel case None } class BioListTableViewController: UITableViewController { var apiThatNeedsToBeCalled:NeededAPI = .None { didSet { //check which API is set and call the function which will call the needed API } } var bioArray = NSArray() { didSet { self.tableView.reloadData() } } 。当用户选择单元格时,您为BioListTableViewController设置了正确的值。执行此操作后,apiThatNeedsToBeCalled中的代码将被执行,并且应该调用调用相应API的函数。

此函数是异步函数,因此只要完成它就会返回。返回时,设置

didSet

触发

self.bioArray = results

显然,self.tableView.reloadData() 需要IBOutlet

答案 1 :(得分:1)

IBOutlet创建tableView,然后在tableView.reloadData()方法中调用viewWillAppear,并确保tableView delegate和{{1}设置为dataSource并且testArray有一些对象。

但是我已经在你的代码中看到了一些基本问题,你应该在用户选择某个选项之后以一种方式构建你的代码,之后你应该从服务器加载数据,如果你将这些数据加载到detailVC中,那就更好了。当你在master中加载数据时,甚至在viewDidLoad方法中的任何用户交互之前我认为不对。可能是使用永远不会选择任何选项,在这种情况下你消耗用户数据,你也应该考虑这一点,它也会消耗内存。

你应该怎么做:将用户选择选项传递给detailVC,即你的情况下的BioListVC,以及在setter方法或viewWillAppear中的fireOff数据加载后面的调用并显示一个微调器,当你有data将其设置为dataSource数组并在主线程上调用reload方法。