SWIFT:快速点击UIButton会导致错误的投票数

时间:2015-11-12 10:13:15

标签: ios swift xcode7

我在下面创建了一个简单的歌曲列表应用程序。

enter image description here

它的工作原理如下: 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)
            }
        }

    }

}

}

1 个答案:

答案 0 :(得分:0)

在按钮操作中,切换按钮userInteractionEnabled属性在开头为NO,在方法结束时为YES。这可能会对你有所帮助