因此,我正在制作类似于Yik Yak的新闻Feed,用户可以在其中发布内容,而其他用户可以对该帖子进行投票或投票。我正在将此功能与Parse集成,并且我已成功完成上传到Parse的投票和下调功能(遵循此处的教程:http://shrikar.com/parse-backed-uitableview-in-ios-8-build-yik-yak-clone-part-2/)。不幸的是,我正在努力弄清楚如何允许用户只进行一次upvote / downvote。
我最初的想法是创建本地存储的布尔值,如果用户已经投票或下注,并使用if / else语句来确定用户是否可以再次投票/下注。这导致我得到以下代码(IBActions连接到upvoting和downvoting按钮):
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
}
}
}
正如我很快意识到的那样,这些布尔人并不是TableView中给定单元格所独有的,所以如果我在A后投票,并且想要投票给B,那么布尔人就会被设置为好像我已经投票了B.第二个问题是,当用户关闭应用程序时,这些将被重置为nil,允许他们在同一帖子上多次投票。
我的下一个想法是使用以下代码使布尔值专用于给定的单元格:
let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint)
我无法弄清楚如何做到这一点。此外,这不能解决用户能够简单地关闭应用程序以重新获得再次投票的能力的问题。
那么,是否有人有解决方案如何允许用户只投票一次?
答案 0 :(得分:1)
好的,所以我找到了一个可以接受的解决方案。这集成了Parse,并且只允许用户upvote和收回upvote(而不是downvoting)。然而,可以按照与我选择的方法类似的方法实现Downvoting(尽管if / else语句有很多)。
class 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与upvote按钮相关联。 "帖子"是包含帖子的Parse类。 " usersHaveUpvoted"是一个数组,包含已提升给定帖子的用户的objectIds。请注意,如果usersHaveUpvoted数组为nil,我的代码将导致应用程序崩溃。我的解决方案是在上传帖子时自动在usersHaveUpvoted数组中放置一个值。但是,解决这个问题的方法可能更为优雅。
唯一的另一个问题是,如果用户足够快地按下upvote按钮两次,则在手机接收到用户已经投票的消息之前,可以两次投票。使用本地数据存储可能有一种聪明的方法。