所以我制作了一个类似于 Yik Yak 中的新闻提要,用户可以在其中发布内容,其他用户可以对该帖子投赞成票或反对票。我正在将这个函数与 Parse 集成,并且我已经成功地制作了上传到 Parse 的赞成票和反对票函数(遵循此处的教程:http://shrikar.com/parse-backed-uitableview-in-ios-8-build-yik-yak-clone-part-2/)。不幸的是,我正在努力弄清楚如何让用户只能投票赞成/反对一次。
我最初的想法是创建本地存储的 bool 值,用于判断用户是否投了赞成票或反对票,并使用 if/else 语句来确定用户是否可以再次投赞成票/反对票。这使我得到了以下代码(IBActions 连接到用于赞成和反对的按钮):
class TableViewController: PFQueryTableViewController {
var hasUpvoted: Bool?
var hasDownvoted: Bool?
@IBAction func yellUpvote(sender: AnyObject) {
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
let object = objectAtIndexPath(hitIndex)
object!.incrementKey("voteCount")
object!.saveInBackground()
self.tableView.reloadData()
NSLog("Top Index Path \(hitIndex?.row)")
if (hasUpvoted == true) {
println("Do nothing, A")
}
if (hasUpvoted == false) {
if (hasDownvoted == true){
println("Add two points, B")
hasUpvoted = true
hasDownvoted = false
}
}
if (hasUpvoted == nil){
if (hasDownvoted == true){
println("Add 2 pts, E")
hasUpvoted = true
hasDownvoted = false
}
if (hasDownvoted == nil){
println("Add 1 point, G")
hasUpvoted = true
}
}
}
@IBAction func yellDownvote(sender: AnyObject) {
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
let object = objectAtIndexPath(hitIndex)
object!.incrementKey("voteCount", byAmount: -1)
object!.saveInBackground()
self.tableView.reloadData()
NSLog("Bottom Index Path \(hitIndex?.row)")
if (hasDownvoted == true) {
println("do nothing, H")
}
if (hasDownvoted == false) {
if (hasUpvoted == true){
println("downvote 2, J")
hasDownvoted = true
hasUpvoted = false
}
}
if (hasDownvoted == nil){
if (hasUpvoted == true){
println ("downvote 2, L")
hasDownvoted = true
hasUpvoted = false
}
if (hasUpvoted == nil) {
println ("downvote 1, N")
hasDownvoted = true
hasUpvoted = false
}
}
}
我很快意识到,这些 bool 值并不是 TableView 中给定单元格所独有的,所以如果我对帖子 A 投赞成票,并想对帖子 B 投赞成票, bool 值将被设置为好像我已经对帖子 B 投了赞成票一样。第二个问题是,这些将在用户关闭应用程序时重置为 nil,从而允许他们对同一个帖子进行多次投票。
我的下一个想法是使用以下代码使 bool 值专用于给定的单元格:
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
虽然我不知道该怎么做。此外,这不会解决用户能够简单地关闭应用程序以重新获得再次投票能力的问题。
那么,对于如何让用户只能投票一次,有没有人有解决方案?
最佳答案
好的,所以我找到了一个可接受的解决方案。这集成了 Parse,并且只允许用户投票和撤回投票(而不是投票)。然而,可以按照与我选择的方法类似的方法来实现向下投票(尽管有更多的 if/else 语句)。
类 TableViewController: PFQueryTableViewController {
var hasUpvoted: Bool?
@IBAction func postUpvote(sender: AnyObject) {
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
let object = objectAtIndexPath(hitIndex)
var hasVotedQuery = PFQuery(className:"Posts")
hasVotedQuery.getObjectInBackgroundWithId(object!.objectId!) {
(post: PFObject?, error: NSError?) -> Void in
if error != nil {
println(error)
}
else if let post = post {
var usersHaveUpvotedArray = post["usersHaveUpvoted"] as? NSArray
println(usersHaveUpvotedArray)
var userObjectId = PFUser.currentUser()?.objectId as String!
let contained = contains(usersHaveUpvotedArray! as! Array, userObjectId)
if (contained == true) {
post.removeObject(userObjectId, forKey: "usersHaveUpvoted")
post.saveInBackground()
object!.incrementKey("voteCount", byAmount: -1)
object!.saveInBackground()
self.tableView.reloadData()
}
if (contained == false) {
post.addUniqueObject(userObjectId, forKey: "usersHaveUpvoted")
post.saveInBackground()
object!.incrementKey("voteCount")
object!.saveInBackground()
self.tableView.reloadData()
}
}
}
}
IBAction 链接到投票按钮。 “帖子”是包含帖子的 Parse 类。 “usersHaveUpvoted”是一个数组,其中包含对给定帖子投了赞成票的用户的 objectId。请注意,如果 usersHaveUpvoted 数组为零,我的代码将导致应用程序崩溃。我的解决方案是在上传帖子时自动在 usersHaveUpvoted 数组中放置一个值。不过,可能有更优雅的方法来解决该问题。
但唯一的另一个问题是,如果用户足够快地按了两次投票按钮,则有可能在手机收到用户已经投票的消息之前投票两次。使用本地数据存储可能是一种聪明的方法。
关于ios - Swift:只允许用户对 TableViewCell 中的项目投票一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31308764/