在 uitableview 单元格中显示项目的评级

Posted

技术标签:

【中文标题】在 uitableview 单元格中显示项目的评级【英文标题】:Show ratings of item in uitableview cell 【发布时间】:2014-12-15 01:55:20 【问题描述】:

我目前正在开发一个 ios 应用程序,该应用程序在 UITableView 中显示 30 个菜单项,然后用户可以在用户点击单元格时显示的详细信息页面上的 5 个启动项中对这些项目进行评分。

现在单元格中当前只是项目的标题,现在我要做的是拥有项目的标题和当前的平均值。标题下方项目的评级。现在我知道如何创建单元格,但是我无法以有效的方式获取电影当前评分的数据。

我目前使用 Parse.com 作为我的后端。现在,当用户提交评分时,它会保存到我在 Parse 上的名为 Ratings 的课程中​​。并且保存了物品的标题和给出的星数。

现在我正在尝试最有效的方法来获取项目的平均星数并将其放入 UITableViewCell。首先,我考虑只执行一个云代码功能,该功能将查询所有 30 个项目,并像 parse.com 文档 https://parse.com/docs/cloud_code_guide#functions 中所做的那样平均评分。

这里的问题是有 30 个或更多项目,然后每个查询都使用一个 API 请求,然后很快就会上升。所以我已经排除了这个选项。另一种方法是一次只显示 5 个项目,然后在用户向下滚动时加载下一个 5,但用户通常会非常快速地滚动多个项目,并且仍然会查看菜单上的所有 30 个项目,所以这不能解决我的问题。

现在我也有自己的服务器,目前我在其中存储了一些正在服务的项目。我在想是否有办法制作 xml 文件或 JSON,当用户保存项目时,我将其保存到 Parse。然后也保存这个文件。

所以这就是我的想法以及我陷入困境的地方。我会使用 Parse.com javascript SDK 制作一个 Cloud Code Job,它每天运行一次。我会让这个函数执行一个查询,以检索在最后一天保存到我的 Ratings 类的所有评级。这会给我所有的对象。现在这就是我卡住的地方:如何从 Parse.com SDK 将此文件放到我的服务器上,以及如何将新评级保存到此文件中?

当然,我愿意接受所有其他有关解决此问题并最小化我的 API 请求的方法的建议。我在想也可能使用 Parse.com 托管来托管 xml 或 JSON 文件?

或者只是一种完全不同的方法,我没有提到。

我知道这是一个很长的问题,我已尽力解释,如果您有任何问题,请提出。

提前感谢您的帮助。我真的很感激:)

编辑

我忘记提到的是这些项目每天都在变化,而且我有多家餐厅,每个餐厅都有自己的项目,所以它是 30 * # 家餐厅。因此,当我在表格视图中显示 30 个项目时,我不确定如何在两个查询中获得所有评级(使用额外的类,我是否还需要查询每个项目)?

编辑 2

好的,现在我有一个 NSMutableArray 填充了评级,我从查询中返回。但是假设我的表格视图中有“一”、“二”和“三”项。并且只有“一”和“三”被评级,然后我会为这些项目获得两个评级,如果在我的 cellForRowAtIndexPath: 方法中我就这样做。像

cell.rating = ratingsArray[indexRow.path];

那么项目二的评分应该是三分...

你看到问题了吗?以及如何绕过它?

谢谢

【问题讨论】:

这是一个有趣的问题,我也遇到了同样的问题。您可以尝试在 Parse SDK 中实现一个“RatingsAverage”类,其属性为:“menu item”、“nbRatings”、“sumOfStars”。当您为 tableview 加载数据时,您必须执行两个 API 请求,一个用于项目,一个用于“RatingsAverage”,并在您的应用程序中执行配对。 'RatingsAverage' 项目仅在为对象创建新评级时更新,但即使在这种情况下您需要更多 API 请求,您也会从 tableview 显示中保存更多 API 请求。 是的,您可能需要另一个类来保存汇总评级。 @MichaëlAzevedo 好的,但我想我没有解释问题的一部分,你能看到编辑你有什么机会 【参考方案1】:

您不需要 Cloud Code Jobs 或其他任何东西。您可以简单地创建另一个具有这些属性的类:itemIdnumberOfVotesaverageRating。当用户发布新评分时,请在其设备上执行以下操作:

averageRating = (averageRating*numberOfVotes + userVote) / (numberOfVotes+1)
numberOfVotes++

并将这两个值存储在云中。当您需要显示平均评分时,只需获取该项目的 averageRating 值即可。

编辑

当我提到额外的课程时,我的意思是您不需要将每个评分都存储在云中。您可以只使用一个类,并且只存储每个项目的平均评分和投票数。您可以通过这样的query 调用通过单个 API 调用获取多个项目的平均评分:

NSArray *ids = @[@"1",
                 @"2",
                 @"3"];
[query whereKey:@"itemId" containedIn:ids];

如果您想存储每个用户的评分(检查用户是否已经对该特定项目进行投票或在另一台设备上显示他的评分),您可以将它们存储在 iCloud 容器中,这样您只需要一个 API 调用当用户投票时,当用户获取 30 个(或任意数量)项目时调用一次。

如果您不需要支持 iOS 7 及更低版本,也可以考虑使用 CloudKit 代替 Parse。

【讨论】:

嘿,谢谢你的帖子你能看到编辑吗我不确定这对我有用 @iqueqiorio 我对答案做了补充。 好的,我现在明白了,但还有一件事是我仍然会使用我的常规评级类为用户保存它,以便我可以显示那里,然后如果用户更新那里的评级我可以查询该类,如果他们尚未对您的代码有效的项目进行评级,但如果他们有您保存到 AverageRating 类的代码,那么我将如何重新保存平均评级,就好像这是评级的更新一样? @iqueqiorio 使用以下公式减去用户评分averageRating = (averageRating*numberOfVotes - oldUserVote) / (numberOfVotes-1)(不要忘记添加除以零检查),然后使用averageRating = (averageRating*numberOfVotes + newUserVote) / numberOfVotes添加新评分 好的,但我需要在保存之前查询 AverageRating 对吗?你怎么知道平均评分是多少以及它的票数是多少?【参考方案2】:

为什么不只有两个属性。 allStars 和 numboerOfReviews。每次有人写评论,

[movie incrementKey"allStars" by whatever the user selects]

[movie incrementKey:"numberOfReviews" byAmount:1]

然后处理平均客户端。 allStars/numberOrReviews

这些应该是 MovieObject 上的属性,当您查询电影时它们将被包括在内,因为它们是基元而不是指针。因此,当您执行 PFQuery 时,如果成功,您将获得一个 PFObjects 数组。将您的 tableViewDataArray 设置为您的查询返回的数组。然后在 cellForRowAtIndexPath 中,您可以访问您的属性,例如 (tableViewDataArray[indexPath.row] as Movie).numberOfStars

【讨论】:

以上是关于在 uitableview 单元格中显示项目的评级的主要内容,如果未能解决你的问题,请参考以下文章

JSON返回null ios时Tableview崩溃

UITableview 单元格中的按钮不会在快速点击时突出显示

如何在 UITableview 单元格中正确显示 JSON 数据?

如何在 Xcode swift 的 UITableview 单元格中显示当前股票价格?

数据未显示在 UITableView 的自定义单元格中

UITableView 每个单元格中有多个项目