我正在使用以下类成功将一行加载到UITableView。
import UIKit
import ResearchKit
enum Activity: Int {
case Demographics
static var allValues: [Activity] {
var idx = 0
return Array(anyGenerator{ return self.init(rawValue: idx++)})
}
var title: String {
switch self {
case .Demographics:
return "Demographics"
}
}
var subtitle: String {
switch self {
case .Demographics:
return "Demographics Survey"
}
}
}
class ActivityViewController: UITableViewController {
// MARK: UITableViewDataSource
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard section == 0 else { return 0 }
return Activity.allValues.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("activityCell", forIndexPath: indexPath)
if let activity = Activity(rawValue: indexPath.row) {
cell.textLabel?.text = activity.title
cell.detailTextLabel?.text = activity.subtitle
if (activity.title == "Demographics"){
if (Data().is_demo_complete()){
cell.textLabel?.textColor = UIColor.lightGrayColor()
cell.detailTextLabel?.textColor = UIColor.lightGrayColor()
cell.userInteractionEnabled = false
}
}
}
return cell
}
func reloadtable(){
self.tableView.reloadData()
}
// MARK: UITableViewDelegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
guard let activity = Activity(rawValue: indexPath.row) else { return }
let taskViewController: ORKTaskViewController
switch activity {
case .Demographics:
taskViewController = ORKTaskViewController(task: DemoTask, taskRunUUID: NSUUID())
}
taskViewController.delegate = self
navigationController?.presentViewController(taskViewController, animated: true, completion: nil)
}
}
我有另一个名为Data
的类,我将所有通信存储到我的服务器。我的想法是我必须检查服务器上的一些数据,以了解是否灰显并禁用tableView中的一行。从数据类,当服务器调用完成并成功时,我这样做:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
ActivityViewController().reloadtable()
})
我已经确认,已成功调用reloadtable()
函数,该函数运行self.tableView.reloadData()
。我被困的地方是,之后,tableView实际上没有重新加载。我可以说,因为我在if let activity = Activity(rawValue: indexPath.row) {
的行上设置了一个断点,并且第二次断点没有被触发,即使我可以确认reloadtable()
函数确实被触发了。我在这里做错了什么,为什么不重新加载表?谢谢!
修改
以下是Data
类:
class Data: NSObject, NSURLSessionDelegate {
var unique_id = UIDevice.currentDevice().identifierForVendor!.UUIDString;
var demo_complete = false
func check_demo_complete(){
let request = NSMutableURLRequest(URL: NSURL(string: "https://www.myurl.com/is_demo_complete.php")!)
request.HTTPMethod = "POST"
let postString = "unique_id=\(unique_id)&pass=somepass"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
if ( responseString == "true" ) {
self.demo_complete = true
print ("Demo has been completed")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
ActivityViewController().reloadtable()
})
}
}
task.resume()
}
func is_demo_complete() -> Bool{
return self.demo_complete
}
}
答案 0 :(得分:1)
问题是ActivityViewController().reloadtable()
电话。每次ActivityViewController
类下载数据时,都会创建一个新的Data
。请务必仅在已存在的同一reloadtable()
实例上调用ActivityViewController
(并在屏幕上显示)。
一个好的(基本但简单的)解决方案是进行以下重构:
func check_demo_complete(completion:(Bool -> ()){
// your network call
dispatch_async(dispatch_get_main_queue()) {
if ( responseString == "true" ) {
completion(true)
}
else {
completion(false)
}
// or, simpler : completion(responseString == "true")
}
}
这样,通过致电check_demo_complete()
,您就有义务通过关闭:
if (activity.title == "Demographics"){
Data().check_demo_complete() { [weak self] success in
if success {
// change your textColors etc
self?.tableView.reloadData()
}
}
}
同样,这是一个应该有效的基本解决方案。要学习的重要一课是:每次需要时都不要创建新的类实例。