2015-07-09 2 views
1

Итак, я делаю канал новостей, подобный тому, который находится в Yik Yak, в котором пользователи публикуют контент, и другие пользователи могут повышать или понижать этот пост. Я интегрирую эту функцию с Parse, и я успешно выполнил функции upvoting и downvoting, которые загружаются в Parse (следуя инструкциям здесь: http://shrikar.com/parse-backed-uitableview-in-ios-8-build-yik-yak-clone-part-2/). К сожалению, я изо всех сил пытаюсь понять, как разрешить пользователю только повышать/понижать один раз.Swift: Разрешите пользователю голосовать только за элемент в TableViewCell

Моя первоначальная идея состояла в том, чтобы создать локально сохраненные булевы, если у пользователя есть upvoted или downvoting, и использовать операторы 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 
     } 
    } 
} 

Как я быстро понял, этот Booleans не является исключительным для данной ячейки в TableView, так что если я upvoted поста A, и хотел бы повысить пост B, булевы будут установлены так, как если бы я уже разместил пост B. Вторая проблема заключается в том, что они будут сброшены на нуль при закрытии приложения пользователем, что позволит им проголосовать несколько раз за такой же почта.

Моя следующая мысль была использовать следующий код, чтобы сделать Booleans исключительно для данной ячейки:

let hitPoint = sender.convertPoint(CGPointZero, toView: self.tableView) 
    let hitIndex = self.tableView.indexPathForRowAtPoint(hitPoint) 

Я не могу понять, как сделать это, хотя. Кроме того, это не решило бы проблему, когда пользователь мог бы просто закрыть приложение, чтобы вернуть возможность повторного голосования.

Итак, есть ли у кого-нибудь решение, как разрешить пользователю голосовать только один раз?

+0

Я предлагаю вам создать объект голосования в Parse, который записывает идентификатор пользователя и идентификатор объекта, на который они голосовали, тогда вы можете проверить эту таблицу для каждого объекта и определить, следует ли включать кнопку голосования на каждом строка таблицы – Paulw11

+0

Эй, я тоже работаю над этим учебником, но, похоже, я не могу заставить комментарии работать. Это сработало для вас? Или любые идеи о том, как я могу улучшить его? Я застрял там –

ответ

1

Итак, я нашел приемлемое решение. Это интегрирует Parse и позволяет пользователю повышать и отменять upvote (в отличие от downvoting). Однако нисходящее движение может быть реализовано в соответствии с аналогичным подходом к тому, который я выбрал (хотя и с гораздо более подробными утверждениями 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 связан с кнопкой upvote. «Посты» - это класс Parse, содержащий сообщения. «usersHaveUpvoted» - это массив, содержащий объектные идентификаторы пользователей, которые поддерживают этот пост. Обратите внимание, что мой код приведет к сбою приложения, если массив usersHaveUpvoted равен нулю. Мое решение для этого автоматически присваивает значение в массиве usersHaveUpvoted при загрузке сообщения. Вероятно, есть более элегантный способ решить эту проблему.

Единственная проблема, однако, состоит в том, что если пользователь нажимает кнопку «вверх» два раза достаточно быстро, можно удвоить, прежде чем телефон получит сообщение, которое пользователь уже имеет. Вероятно, существует разумный способ сделать это, используя локальное хранилище данных.

+0

Привет, я пытался выяснить, что вы делали! Мне было интересно, успешно ли вы получили это голосование? Я попробовал код, добавленный вами в ответ выше, но я просто получаю 'nil', напечатанный в журналах ... Я разместил здесь вопрос, http://stackoverflow.com/questions/35878086/make-a-voting- system-with-parse-in-swift, можете ли вы мне помочь? заранее спасибо – Nick89

Смежные вопросы