4

非常简单的用例:假设一个 iOS 应用程序显示一个带有电影列表的MovieListController视图(在 a 内)。UINavigationController当用户触摸一个时,应用程序将 a 推MovieDetailController送到导航堆栈上(即[[MovieDetailController alloc] initWithMovieId:(NSString *)。在MovieDetailController'sviewDidAppear:方法中,它进行 HTTP 调用以根据传递给它的电影 ID 检索详细信息。

挑战在于立即将其MovieDetailController推送到导航堆栈上,并且在尚未检索到详细信息的一两秒钟内,视图会显示一堆空白字段,这是不可取的。

为了解决这个问题,我正在考虑MovieListController不要MovieDetailController立即将其推入堆栈。相反,它会设置一个进度指示器(我使用的是 SVProgressHUD),然后调用将启动 HTTP 调用MovieDetailController的方法。initWithMovieId:然后当接收到数据时,MovieDetailController会进行回调MovieListController以删除进度指示器,然后将其推MovieDetailController送到导航堆栈上。

这种情况有更好的模式吗?我是否应该考虑在MovieDetailController准备好时将其推送到导航堆栈上?

注意:我考虑过加载详细视图并放置一个活动指示器,但您仍然可以在它后面看到一个看起来有点奇怪的“空视图”。我也考虑过只MovieListController检索细节本身,但这似乎打破了封装模型——MovieListController应该只关心列出电影,而不是它们的细节。

有什么想法吗?这部电影的东西只是一个例子 - 在这里寻找一般模式。

4

3 回答 3

5

我个人会采取以下方法。

  1. 用户选择他们想要详细信息的电影
  2. 推送到详细视图,而不是显示带有空字段的骨架视图,覆盖加载视图,您可以在此之上继续使用进度 HUD 来获得任何动画。
  3. 一旦结果出来,删除你的HUD和隐藏所有数据/字段的加载覆盖视图

我会走这条路线而不是在推送视图控制器之前显示 HUD 的原因是您可以让用户有机会取消他们的选择。我不熟悉,SVProgressHUD但希望当显示 HUD 时,您可以启用触摸,特别是如果用户UINavigationController不小心选择了电影或请求花费的时间比他们愿意等待的时间长,则用户会触摸返回。

它还将逻辑与您的列表视图分开,您的详细视图是独立的,可以在您的应用程序的任何位置初始化(也许您想在电影详细视图中交叉链接类似的电影)并且您不需要重写呈现的逻辑查看等待结果回来。

于 2013-06-27T23:48:09.500 回答
2

在这种情况下,我个人会回到模型-视图-控制器模式。

有几个系统应用程序会显示来自对象列表的详细视图,例如日历、联系人等。据推测,与EKEvent它们ABPerson各自的应用程序一样,主视图控制器维护模型对象的列表。当用户选择其中一项时,主视图控制器将所选模型对象传递给详细视图控制器。详细视图控制器本身不必进行任何数据加载。因此,就像@ChrisWagner 所说,我们希望将逻辑与视图控制器分开。

方法

同样,您可能希望使用MovieList存储对象数组的类Movie。每个都Movie存储详细视图控制器中所有字段的值 - 本质上,是应用程序需要的有关电影的所有信息。例如,您可能有一个属性NSString *movieTitle,或NSDate *premiereDatemovieTitle将由 at 初始化设置,因为MovieList它只是元数据;另一方面,premiereDate可能是nil数据尚未加载,因此您将有一个属性BOOL isLoaded来检查这种情况。

然后,您可以通过以下两种方式之一进行:

1)假设主视图控制器想要为电影推送细节视图控制器。然后主视图控制器会从中挖掘出适当Movie的内容MovieList并检查它是否已加载。如果没有,它会在模型​​对象完成加载时调用类似-(void)loadContents的东西Movie.,它会发布一个通知它已经完成加载。此时主视图控制器将关闭其进度视图并推送详细视图。如果您使用 (1),那么使用MovieList协调器就没有那么重要了。

2)如果你想更积极地加载电影信息,你可以实现一个方法MovieList,在后台调用loadContentsMovie的 s 。然后,当用户选择电影时,电影已经加载的可能性更高。

编辑:请注意,如果您决定使用MovieList类型对象,则应仅允许主视图控制器访问此列表。在某种程度上,我描述的模型结构与视图控制器结构相似。细节视图控制器不知道列表视图控制器,所以它也不应该知道MovieList

益处

使用这个MovieMovieList结构的好处是数据模型与视图控制器完全分离。这样,用户可以在数据加载时自由地取消、选择、呈现和关闭视图控制器。(想象一下,如果用户按下 Back 来关闭进度 HUD,取消它本来会收集的任何 HTTP 数据。然后,如果他决定回到同一部电影,新的细节视图控制器必须重新开始加载。)另外,如果您决定在开发过程中替换视图控制器类,您将不必复制和粘贴一堆数据处理代码。

我想您会发现以这种方式构建您的应用程序不仅可以为您和用户提供更多的自由,还可以使您的应用程序高效并且对以后的扩展开放。(很抱歉这么晚才发帖,但我想在这个与模式相关的讨论中包括 MVC!)

于 2013-07-02T17:35:37.767 回答
1

我认为更高级的路线是在表格视图/集合视图中显示单元格时开始详细请求。然后当单元格移出屏幕时,取消请求。您可能会不必要地加载电影详细信息,但我认为这没什么大不了的,因为您只会用您可能不需要的电影详细信息填充数据库,而 coredata 可以处理。这是假设您的 api 请求发生在 bg 线程上并且它们不影响主(UI)线程。

于 2013-07-03T02:31:19.127 回答