在我的应用程序中,我有两个表视图。第一个表视图具有一定数量的单元格。 这些细胞将永远是相同的,永远不会改变。
见下文:
上面的表视图将始终具有3个单元格,而且永远不会更多。 在我的服务器上,我有我的API,其中包含每个单元格的路由。
例如:
GET - myAPI / game
GET - myAPI / book
GET - myAPI / travel
每条路线发回不同的数据。
我想要做的是,当用户点击表格视图单元格时,它会将它们带到新的表格视图,其中的单元格包含来自API的响应。
目前我的2ND表视图为空,见下文:
这是我到目前为止所尝试的内容:
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返回的内容。
答案 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方法。