将数据从一个表视图传递到另一个表视图

Passing data from One tableview to Another

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

见下文:

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

例如:

获取 - myAPI/game

获取 - myAPI/book

获取 - myAPI/travel

并且每条路由返回不同的数据。

我想做的是,当用户单击 table 视图单元格时,会将他们带到一个新的 table 视图,该视图的单元格包含来自API.

目前我的第 2 个 table 视图是空的,见下文:

这是我目前尝试过的:

 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




            }
          }
        }
      }

生物列表视图控制器CLASS代码:

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 返回的内容。

tableView创建一个IBOutlet,然后在viewWillAppear方法中调用tableView.reloadData(),并确保tableView delegatedataSource 设置为 viewController 并且 testArray 有一些对象。

但是我在你的代码中看到了一些基本问题,你应该以用户 select 的一些选项来构建你的代码,然后你应该从服务器加载数据,如果你加载会更好detailVC 中的数据,目前您正在 master 中加载数据,甚至在我认为不正确的 viewDidLoad 方法中进行任何用户交互之前。可能永远不会使用 select any 选项,在这种情况下你正在消耗用户数据,你也应该考虑一下,它也会消耗内存。

你应该做什么: 将用户 select 选项传递给 detailVC 即 BioListVC 在你的情况下,在 setter 方法或 viewWillAppear fireOff 中数据加载在后台调用并显示微调器,当您将数据设置为 dataSource 数组并在主线程上调用 reload 方法时。

检查您的数据在您的单元格被点击之前是否已正确下载,这意味着 self.testArray 而不是 nil

EDIT: 您可以使用全局 NSMutableDictionary 属性,例如 testArray,然后调用 3 api 来获取 3 个不同的数据:

    NSMutableDictionary *testDictionary = [NSMutableDictionary new];
   [testDictionary setValue:testArray1 forKey:@"books"];
   [testDictionary setValue:testArray2 forKey:@"travels"];
   [testDictionary setValue:testArray3 forKey:@"anykeys"];

并且在你的 segue 中,使用 [testDictionary valueForKey:@"books"]

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

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

这是你应该做的。

在你的 BioListTableViewController 中创建一个变量,它将确定需要调用哪个 API(也许值得将其设为 enum):

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()
    }
}

您现在要做的是将API调用逻辑移至BioListTableViewController。当用户选择单元格时,您可以为 apiThatNeedsToBeCalled 设置正确的值。执行此操作后,didSet 中的代码将被执行,它应该调用调用适当 API.

的函数

此函数是一个异步函数,因此它会在完成时 return。当它 returns 时,你设置

self.bioArray = results

哪个触发

self.tableView.reloadData()

显然,您的 tableView 需要一个 IBOutlet