拇指向下 - YouTube风格的投票系统,用户只能投票一次,但可以从喜欢变为不喜欢反之亦然

时间:2015-10-27 03:41:39

标签: ios swift voting rating-system

我正在制作一个用户可以发帖/评论/喜欢帖子的应用程序。我想实现类似于YouTube的大拇指/向下。我当前有两个IBActions用于喜欢和不喜欢的按钮。我的问题是,如何在选择其他按钮时取消选择按钮并减小/增加每个按钮的值?反之亦然?以下是代码。

@IBAction func dislikeButton(sender: UIButton) {



    let selected: Bool = !sender.selected

    var likeCount: Int = Int((sender.titleLabel?.text)!)!

    if selected {
        //upvote
        likeCount++
        print("inc \(likeCount)")

    } else {
        //downvote, but do not allow negative values
        if likeCount == 0{
            likeCount = 0
        } else {
            likeCount--
        }
        print("dec \(likeCount)")
    }
    sender.setTitle(String(likeCount), forState: UIControlState.Normal)
    sender.selected = !sender.selected


}





@IBAction func likeButton(sender: UIButton) {

    let selected: Bool = !sender.selected

    var dislikeCount: Int = Int((sender.titleLabel?.text)!)!

    if selected {

        //upvote
        dislikeCount++
        print("inc \(dislikeCount)")

    } else {
        //downvote, but do not allow negative values
        if dislikeCount == 0{
            dislikeCount = 0
        } else {
            dislikeCount--
        }
        print("dec \(dislikeCount)")
    }
    sender.setTitle(String(dislikeCount), forState: UIControlState.Normal)
    sender.selected = !sender.selected

}

1 个答案:

答案 0 :(得分:1)

将模型与视图分开通常是更好的设计。也就是说,更好的设计(在你的情况下)存储用户的投票(如/ dislike / none)和投票直接计数,而不是隐含地按钮按钮状态和标签。

class VotableItem {

    // Votes: -1 for dislike, 1 for like, 0 for no vote
    var vote: Int = 0 // initialize to user's existing vote, retrieved from the server
    var likeCount: Int = 0 // initialize to existing like count, retrieved from the server
    var dislikeCount: Int = 0 // initialize to existing dislike count, retrieved from the server

你还需要连接到喜欢和不喜欢按钮的插座来更新它们:

    @IBOutlet var likeButton: UIButton!
    @IBOutlet var dislikeButton: UIButton!

当用户单击“赞”按钮时,有两种可能的操作。如果现有投票是“喜欢”(存储为1),她想撤消她的“喜欢”投票并将她的投票设置回“无”(存储为0)。否则,现有的投票要么是“无”或“不喜欢”(存储为-1),她想取消现有投票并将其投票设为“赞”。

同样,当用户单击“不喜欢”按钮时,有两种可能的操作。如果她现有的投票是“不喜欢”,她想撤消它,将其设置为“无”。否则,她想撤销她现有的“喜欢”或“无”投票,并将她的投票设定为“不喜欢”。

请注意,撤消“无”投票无效,但如果我们允许撤消它(通过什么都不做),逻辑会更简单。

由于Like和Dislike按钮的动作非常相似,我们可以将常见行为分解出来。将按钮连接到这些操作:

    @IBAction func dislikeButtonWasClicked(sender: UIButton) {
        buttonWasClickedForVote(-1)
    }

    @IBAction func likeButtonWasClicked(sender: UIButton) {
        buttonWasClickedForVote(1)
    }

然后实现buttonWasClickedForVote(_:)函数:

    private func buttonWasClickedForVote(buttonVote: Int) {
        if buttonVote == vote {
            // User wants to undo her existing vote.
            applyChange(-1, toCountForVote: vote)
            vote = 0
        }

        else {
            // User wants to force vote to toggledVote.
            // Undo current vote, if any.
            applyChange(-1, toCountForVote: vote)
            // Apply new vote.
            vote = buttonVote
            applyChange(1, toCountForVote: vote)
        }

        updateUserInterfaceFromModel()
    }

我正在使用辅助函数来更新计数。请注意,如果投票为0(意味着“无”),它什么都不做:

    private func applyChange(change: Int, toCountForVote vote: Int ) {
        if vote == -1 { dislikeCount += change }
        else if vote == 1 { likeCount += change }
    }

我们需要另一个函数来使UI状态与模型匹配:

    private func updateUserInterfaceFromModel() {
        likeButton.selected = vote == 1
        likeButton.setTitle("\(likeCount)", forState: .Normal)
        dislikeButton.selected = vote == -1
        dislikeButton.setTitle("\(dislikeCount)", forState: .Normal)
    }

请注意,updateUserInterfaceFromModel函数不依赖于用户界面的当前状态。这意味着您也可以在初始化期间使用它。只需设置votelikeCountdislikeCount(可能是基于服务器的数据)。然后,在viewDidLoad中,拨打updateUserInterfaceFromModel