我在下面创建了一个简单的歌曲列表应用程序。
它的工作原理如下: 1.用户可以将歌曲添加到列表中(使用“+”图标) 2.使用可以点击投票按钮增加或减少他们的投票。它与Facebook上的“LIKE”按钮类似。
正如您所看到的,一些投票计数是负数。原因是因为在QA期间,我非常快地点击了“投票”按钮,这导致投票数量变得混乱。我不认为这是一个会发生很多的情景,但有没有人有创造性的方法来防止这种情况发生?任何解决方案将不胜感激。谢谢。
如果需要,我可以添加我的代码,但我希望有一个简单的解决方案,我还没有找到。
更新:为表视图控制器和表视图单元添加了代码 -
表视图单元格(使用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)")
}
}
}
表视图控制器:
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)
}
}
}
}
}
答案 0 :(得分:0)
在按钮操作中,切换按钮userInteractionEnabled属性在开头为NO,在方法结束时为YES。这可能会对你有所帮助