3

关于何时使用 UIViewContoller 与 UIView 有一些很好的答案。例如这里这里

一般的要点是应该使用 UIVIewController 来控制全屏数据,因为

  1. 它旨在处理旋转。一次只能在屏幕上显示一个 UIViewController,因为只有最新的才会被通知发生了旋转。

  2. 为了忠实于 MVC 范式,您的业务逻辑应该存在于 UIViewController 中,而只有显示和交互逻辑应该存在于 UIView 中。大概业务逻辑与整个屏幕上的内容有关。

我的问题是,鉴于此,我如何构建一个在多个顶级视图之间进行左右分页的应用程序?

我想创建一个包含几个 UITableViews 的界面,其中包含一个食谱列表。用户左右滑动以在列表之间导航。底部有一个通用菜单,无论如何都保持固定。

我最初的想法是为 UIScrollView 使用一个 UIVIewController,然后从那里添加子视图。

但是我真的希望每个列表都有自己的 UIViewController,这样它就可以处理自己的旋转,并像自己的 REST 方法一样保存业务逻辑。让顶级 UIViewController 处理子子视图的旋转似乎很痛苦,将逻辑放在其他任何地方似乎违反了 MVC。

有没有办法构建一个应用程序,使多个 UIViewControllers 存在于一个 UIScrollView 中,或者使用一系列顶级 UIViewControllers 和 UISwipeGestureRecognizer 来模拟 UIScrollView 的分页效果是否合适?

谢谢。

4

4 回答 4

2

几个想法:

  1. 如果针对 iOS 5 及更高版本,我建议使用专为此 UI 设计的(在实例UIPageViewController之间来回滑动)。UIViewController然后,您将有一个单独UIViewController的每个食谱。在 iOS 5 中,你只有UIPageViewControllerTransitionStylePageCurl 过渡样式,但在 iOS 6 中,你也有UIPageViewControllerTransitionStyleScroll.

    有关更多信息,请参阅iOS 视图控制器目录的页面视图控制器部分。

  2. 这比编写自己的基于滚动视图的解决方案要简单得多。如果您使用 a “滚动自己的” UIScrollView,您将需要删除已滚动到屏幕外的实例(通过注册为滚动视图delegate并响应scrollViewDidScroll),这样您就不会不必要地占用内存。

    如果您确实将子视图控制器添加到滚动视图,请不要忘记调用适当的自定义容器调用。具体来说,当您将视图控制器添加到滚动视图时,请确保调用以下内容(假设controller是子控制器并且self是主视图控制器):

    [self addChildViewController:controller];
    [self.scrollView addSubview:controller.view];
    [controller didMoveToParentViewController:self];
    

    当您响应scrollViewDidScroll删除不再可见的视图控制器时,请执行适当的删除调用,例如:

    [controller willMoveToParentViewController:nil];
    [controller.view removeFromSuperview];
    [self removeChildViewController:controller];
    

    有关调用这些自定义容器调用为何如此重要的信息,请参阅 WWDC 2011 视频实施 UIViewController Containment

  3. 不过,我绝对不建议使用 a UINavigationController,因为它会将所有以前的页面保存在内存中。

于 2013-10-17T21:12:02.390 回答
1

我相信对于您所说的要求,您可以使用UINavigationController. 它会给你你想要的“左右”分页,你可以UIViewController为你的每个食谱使用一个。

另外,我认为您想使用 aUIScrollView因为它可以让您执行“滑动”手势。如果是这种情况,您还可以将 a 添加UISwipeGestureRecognizer到您的视图控制器中,并且每次识别手势时调用pushViewController:animated:popViewControllerAnimated:在您的食谱之间执行导航。

这是正义和想法。

希望这可以帮助!

于 2013-10-17T20:51:59.910 回答
1

据我所知,有两个不错的选择:

  1. 根据滑动手势的方向使用根 UINavigationController 和推送/弹出子 ViewController(正如您所说,由 UISwipeGestureRecognizer 识别)。

  2. 使用带有 UIScrollView 的根 UIViewController 并将子 viewcontroller 视图添加为滚动视图的子视图。要处理方向更改,您可以将方向更改 UIViewController 方法 ( willRotateToInterfaceOrientation, didRotateFromInterfaceOrientation) 传递给子控制器,以便它们可以处理它们。

我希望我有所帮助

于 2013-10-17T20:55:11.740 回答
1

首先,您应该知道,从 iOS 5 开始,可以在主视图控制器中包含子视图控制器。

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

所以在我看来,一个不错的选择是将分页的 UIScrollView 作为您的主控制器,然后将您的子控制器的实例放到每个页面上。

由于这可能会占用大量内存,因此您在任何时候实际上都应该只有三个实例(显示一个,两侧各一个,以便在用户开始滚动时它们已准备好)。Apple 演示项目向您展示了如何配置这样的滚动视图:

https://developer.apple.com/library/ios/samplecode/PageControl/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007795

希望有帮助。

于 2013-10-17T21:12:55.147 回答