我在下面创建了一个简单的歌曲列表应用程序。
其工作原理如下: 1. 用户可以将歌曲添加到列表中(使用“+”图标) 2. 用户可以点击投票按钮来增加或减少自己的投票。它的工作原理类似于 Facebook 上的“LIKE”按钮。
如您所见,部分票数为负数。原因是在质量检查期间,我极快地点击了“投票”按钮,导致投票计数失控。我不认为这种情况会经常发生,但是有人有创造性的方法来防止这种情况发生吗?任何解决方案将不胜感激。谢谢。
如果需要,我可以添加我的代码,但我希望有一个我尚未找到的简单解决方案。
更新:添加了 TableView Controller 和 TableView 单元格的代码 -
表格 View 单元格(带有“投票”的 UIButton 操作):
@IBAction func voteButton(sender: UIButton) {
var query = PFQuery(className:"UserVotes")
//query the database to check if the user actually like the song in the paticular row that's clicked
query.whereKey("username", equalTo: (PFUser.currentUser()?.username)!)
query.whereKey("song", equalTo: songID!)
query.whereKey("vote", equalTo: true)
query.findObjectsInBackgroundWithBlock {
(object: [PFObject]?, error: NSError?) -> Void in
if error == nil {
//this is the case where a TRUE value is found. LIKE is ON
if object!.count > 0 {
if let object = object! as? [PFObject] {
for object in object {
if self.delegate != nil && self.rowValue != nil {
//decrease the count by 1
self.voteCount = self.voteCount! - 1
self.votes.text = "\(self.voteCount!)"
self.voteButtonOn = true
self.delegate!.voteButtonTurnOffFromCellRow(self.rowValue!)
print(self.voteButtonOn)
}
}
}
//this is the case where a TRUE value is NOT found, LIKE is OFF.
} else if object?.count == 0 {
if self.delegate != nil && self.rowValue != nil {
//increase the count by 1
self.voteCount = self.voteCount! + 1
self.votes.text = "\(self.voteCount!)"
self.voteButtonOn = false
self.delegate!.voteButtonTurnOnFromCellRow(self.rowValue!)
print(self.voteButtonOn)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
}
TableView Controller :
import UIKit
import Parse
protocol VoteProtocol {
func voteButtonTurnOnFromCellRow(row: Int)
func voteButtonTurnOffFromCellRow(row: Int)
}
class MusicPlaylistTableViewController: UITableViewController, VoteProtocol {
var usernames = [String]()
var songs = [String]()
var songVotes = [Int]()
//Function to display an alert
func displayAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.separatorColor = UIColor.grayColor()
let query = PFQuery(className:"PlaylistData")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects! as? [PFObject] {
self.usernames.removeAll()
self.songs.removeAll()
for object in objects {
let username = object["username"] as? String
self.usernames.append(username!)
let track = object["song"] as? String
self.songs.append(track!)
let votes = object["numVotes"] as? Int
self.songVotes.append(votes!)
}
self.tableView.reloadData()
}
} else {
print(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return usernames.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellTrack", forIndexPath: indexPath) as! TrackTableViewCell
cell.username.text = usernames[indexPath.row]
cell.songTitle.text = songs[indexPath.row]
var voteCount: Int = songVotes[indexPath.row]
var voteCountString = String(voteCount)
cell.votes.text = voteCountString
cell.delegate = self
cell.rowValue = indexPath.row
cell.songID = songs[indexPath.row]
cell.voteCount = songVotes[indexPath.row]
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
}
//If the LIKE button is OFF perform this. This means that a record in the database has NOT been found with a value of TRUE.
func voteButtonTurnOnFromCellRow(var row: Int) {
// At this point, the value needs to be changed to TRUE, and the vote count needs to be increased by 1.
//note: does not take into account scenario where there are duplicate records (slight case)
let query = PFQuery(className:"UserVotes")
query.whereKey("username", equalTo: (PFUser.currentUser()?.username)!)
query.whereKey("song", equalTo: songs[row])
query.whereKey("vote", equalTo: false)
query.findObjectsInBackgroundWithBlock { (object: [PFObject]?, error: NSError?) -> Void in
if error == nil {
//this is the case where a FALSE value is found. LIKE is OFF
if object!.count > 0 {
if let object = object! as? [PFObject] {
for object in object {
object["vote"] = true
object.saveInBackground()
let query = PFQuery(className:"PlaylistData")
query.whereKey("song", equalTo: self.songs[row])
query.findObjectsInBackgroundWithBlock { (object: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let object = object! as? [PFObject] {
for object in object {
var voteCount:Int = object["numVotes"] as! Int
voteCount = voteCount + 1
object["numVotes"] = voteCount
object.saveInBackground()
}
}
}
}
}
}
//this is the case where a TRUE value is NOT found, LIKE is OFF (first time user vote)
} else if object?.count == 0 {
//add row to table
let addUserVote = PFObject(className: "UserVotes")
addUserVote["song"] = self.songs[row]
addUserVote["username"] = PFUser.currentUser()?.username
addUserVote["vote"] = true
addUserVote.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
if let error = error {
if let errorString = error.userInfo["error"] as? String {
self.displayAlert("Error", message: errorString)
}
} else {
let query = PFQuery(className:"PlaylistData")
query.whereKey("song", equalTo: self.songs[row])
query.findObjectsInBackgroundWithBlock { (object: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let object = object! as? [PFObject] {
for object in object {
var voteCount:Int = object["numVotes"] as! Int
voteCount = voteCount + 1
object["numVotes"] = voteCount
object.saveInBackground()
}
}
}
}
}
} else {
// There was a problem, check error.description
}
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
}
//If the LIKE button is ON perform this. This means that a record in the database has been found with a value of TRUE.
func voteButtonTurnOffFromCellRow(var row: Int) {
// At this point, the value needs to be changed to FALSE, and the vote count needs to be decreased by 1.
//note: does not take into account scenario where there are duplicate records (slight case)
let query = PFQuery(className:"UserVotes")
query.whereKey("username", equalTo: (PFUser.currentUser()?.username)!)
query.whereKey("song", equalTo: songs[row])
query.whereKey("vote", equalTo: true)
query.findObjectsInBackgroundWithBlock { (object: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let object = object! as? [PFObject] {
for object in object {
object["vote"] = false
object.saveInBackground()
let query = PFQuery(className:"PlaylistData")
query.whereKey("song", equalTo: self.songs[row])
query.findObjectsInBackgroundWithBlock { (object: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let object = object! as? [PFObject] {
for object in object {
var voteCount:Int = object["numVotes"] as! Int
voteCount = voteCount - 1
object["numVotes"] = voteCount
object.saveInBackground()
}
}
}
}
}
} else {
print(error)
}
}
}
}
}
最佳答案
在按钮操作中,将按钮 userInteractionEnabled 属性在方法的开头切换为 NO,在方法结束时切换为 YES。这可能对你有帮助
关于ios - SWIFT:快速点击 UIButton 会导致选票计数不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33668980/