【问题标题】:Thumbs Down - YouTube style voting system where user can only vote once but can change from like to dislike vice versaThumbs Down - YouTube 风格的投票系统,用户只能投票一次,但可以从喜欢变为不喜欢,反之亦然
【发布时间】:2015-10-27 03:41:38
【问题描述】:

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

@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

}

【问题讨论】:

    标签: ios swift voting rating-system


    【解决方案1】:

    将模型与视图分开通常是更好的设计。也就是说,更好的设计(在您的情况下)存储用户的投票(喜欢/不喜欢/无)并直接计算投票,而不是隐含地作为按钮状态和标签。

    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!
    

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

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

    请注意,撤消“无”投票无效,但如果我们允许撤消它(不做任何事情),逻辑会更简单。

    由于“喜欢”和“不喜欢”按钮的操作非常相似,我们可以分解出共同的行为。将按钮连接到这些操作:

        @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

    【讨论】:

    • 嘿,非常感谢您的回答!如何将其存储在 Parse 数据库中?
    • 您需要为此阅读 Parse 文档,并且可能按照 Parse 教程学习 API。
    • 谢谢。我尝试了您的代码,但在此处出现错误:最后一个函数:func updateUserInterfaceFrommodel() .. 我遇到了致命错误:在展开可选值时意外发现 nil...感谢您的帮助!
    • 我怀疑您没有在情节提要中连接 likeButtondislikeButton 出口。
    • 非常感谢。如果我要在 Parse 中存储喜欢/不喜欢计数,我会存储前 3 个声明的变量(投票、likeCount 和 dislikeCount)吗?还是只是投票?
    猜你喜欢
    • 2011-09-29
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 2018-05-27
    • 2022-12-13
    相关资源
    最近更新 更多