class NewsTableViewController: UITableViewController {
@IBOutlet weak var authenticationButton: UIBarButtonItem!
var blogPosts = []
override func viewDidLoad() {
super.viewDidLoad()
// 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()
self.navigationItem.title = PFConfig.currentConfig().objectForKey("title") as? String
authenticationButton.enabled = true
if let authEnabled:Bool = PFConfig.currentConfig().objectForKey("adminEnabled") as? Bool {
if authEnabled {
authenticationButton.tintColor = UIView.appearance().tintColor
} else {
authenticationButton.tintColor = UIColor.darkGrayColor()
}
}
loadPosts()
//set the title
PFConfig.getConfigInBackgroundWithBlock { (var config: PFConfig!, var error: NSError!) -> Void in
if error == nil {
if let title:String = config.objectForKey("title") as? String {
self.navigationItem.title = title
}
if let authEnabled:Bool = config.objectForKey("adminEnabled") as? Bool {
if authEnabled {
self.authenticationButton.tintColor = UIView.appearance().tintColor
} else {
self.authenticationButton.tintColor = UIColor.darkGrayColor()
}
}
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return blogPosts.count
}
@IBAction func authenticate(sender: UIBarButtonItem) {
//check if enabled, and if not, get error message from config
if sender.tintColor != UIColor.darkGrayColor() {
//enabled
var authAlert = UIAlertController(title: "Authenticate", message: "Please login to access the admin page.", preferredStyle: UIAlertControllerStyle.Alert)
authAlert.addTextFieldWithConfigurationHandler({(textField: UITextField!) in
textField.placeholder = "Password"
})
authAlert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
authAlert.addAction(UIAlertAction(title: "Go", style: UIAlertActionStyle.Default, handler: { (goAction) -> Void in
let textField:UITextField = authAlert.textFields![0] as UITextField
let text = textField.text
self.authenticateUser(text)
}))
self.presentViewController(authAlert, animated: true, completion: nil)
} else {
//disabled
var serverMessage = PFConfig.currentConfig().objectForKey("adminEnabledMessage") as? String
var errorMessage = UIAlertController(title: "Error", message: "The Admin Console is not enabled right now. Message from server: \(serverMessage!)", preferredStyle: UIAlertControllerStyle.Alert)
errorMessage.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(errorMessage, animated: true, completion: nil)
}
}
//authHandlers
func authenticateUser(password: String) {
//get the server password
let serverPass = PFConfig.currentConfig().objectForKey("password") as? String
if password == serverPass {
//move them to the admin console
self.performSegueWithIdentifier("showConsole", sender: nil)
} else {
//error message
var errorMessage = UIAlertController(title: "Error", message: "Incorrect password, please try again.", preferredStyle: UIAlertControllerStyle.Alert)
errorMessage.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(errorMessage, animated: true, completion: nil)
}
}
func loadPosts() {
let query = PFQuery(className: "Posts")
query.findObjectsInBackgroundWithBlock { (objects, error: NSError!) -> Void in
if error == nil {
self.blogPosts = objects
self.tableView.reloadData()
} else {
var errorMessage = UIAlertController(title: "Error", message: "There was an error retrieving the posts. Please try again later. \(error.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert)
errorMessage.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(errorMessage, animated: true, completion: nil)
}
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as PostTableViewCell
// Configure the cell...
let currentPost:PFObject = blogPosts.objectAtIndex(indexPath.row) as PFObject
let title = currentPost.objectForKey("title") as String
cell.titleLabelC.text = title
let gmtFormatter:NSDateFormatter = NSDateFormatter()
gmtFormatter.dateFormat = "E MMM d @ hh:mm a"
let dateString = gmtFormatter.stringFromDate(currentPost.createdAt)
cell.detailsLabelC.text = dateString
return cell
}
这是我添加到故事板的UITableView的代码。出于某种原因,当我在loadPosts()中调用self.tableView.reloadData()时,它不会更新表,也不会调用cellForRowAtIndexPath。知道为什么吗?
答案 0 :(得分:1)
您的TableViewDataSource总是为部分数返回0,但您至少需要1.只需删除该DataSource函数,因为它默认为1。
答案 1 :(得分:0)
有关多线程的此错误。
UITableView - 它是UI元素。 UI仅适用于主线程。这意味着reloadData也只能在main thred中运行。
在您的代码query.findObjectsInBackgroundWithBlock
中是异步方法。因此reloadData在此方法中不起作用。
你应该通过GCD在主线程中调用它。
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})