使用UINavigationController在UIPageViewController中下载内容

更新2

我一直在使用4英寸的设备在iOS模拟器上运行并testing我的应用程序。 如果我使用3.5英寸设备运行,标签不会跳转。 在我的.xib中,在模拟指标下,我将它设置为Retina 4英寸全屏幕。 任何想法,为什么我只在4英寸的设备上看到这个问题?

更新1

在IB中,如果我在“模拟指标”中select“导航栏”,我的标签仍会跳跃。 唯一可以让我的标签在第一个屏幕上正确呈现的方法是不要将导航控制器设置为我的窗口的根视图控制器。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我的窗口的rootViewController被设置为一个UINavigationController,其rootViewControllerembedded了一个UIPageViewController。

当我的应用程序加载时,初始视图会显示其内容,与导航栏的大小大致相同。 当我滚动pageViewController,内容跳转到它被放置在笔尖的位置,并由pageViewController加载的所有其他viewControllers罚款。

带导航控制器的uipageviewcontroller

在我的AppDelegate中:

self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ContainerViewController new]]; 

在ContainerViewController中:

 - (void)viewDidLoad { [super viewDidLoad]; self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; self.pvc.dataSource = self; self.pvc.delegate = self; DetailViewController *detail = [DetailViewController new]; [self.pvc setViewControllers:@[detail] direction:UIPageViewControllerNavigationDirectionForward animated:false completion:nil]; [self addChildViewController:self.pvc]; [self.view addSubview:self.pvc.view]; [self.pvc didMoveToParentViewController:self]; } 

所以我在进一步的发展之后又增加了一个答案,我终于想到了我究竟发生了什么。 好像在iOS7中,UIPageViewController有它自己的UIScrollView。 因此,您必须将AdjustsScrollViewInsets automaticallyAdjustsScrollViewInsets设置为false。 这是我的viewDidLoad现在:

 - (void)viewDidLoad { [super viewDidLoad]; self.automaticallyAdjustsScrollViewInsets = false; DetailViewController *detail = [[DetailViewController alloc] init]; [self setViewControllers:@[detail] direction:UIPageViewControllerNavigationDirectionForward animated:false completion:nil]; } 

没有必要把任何东西viewWillLayoutSubviews (作为我以前的答案之一build议)。

这肯定是由automaticallyAdjustsScrollViewInsets ScrollViewInsets和其他海报(包括@ djibouti33)造成的。 但是,这个属性有两个奇怪的地方:

  1. 它必须在UINavigationController上设置。 如果您将其设置在由UINavigationControllerpipe理的子控制器上,则不会产生任何影响。 1
  2. 它仅适用于控制器子视图中的滚动视图位于索引零时。 2

这两个警告应该解释线程中其他人遇到的间歇性问题。

TLDR:我所使用的解决方法是在索引为零的位置向UIPageViewController添加一个虚拟视图,以避免设置应用于页面控制器中的scrollView,如下所示:

 pageViewController.view.insertSubview(UIView(), atIndex: 0) // swift [pageViewController.view insertSubview: [UIView new] atIndex: 0]; // obj-c 

更好的办法是自己设置滚动视图上的contentInset ,但不幸的是UIPageViewController不公开滚动视图。

只需取消选中Under Top Bars ”即可: UIPageViewController和您的自定义PageContentViewController

在这里输入图像说明

我原来的答案暂时解决了这个问题,但过了一段时间,同样的问题又回来咬我。

使用以下viewController层次结构:

 -- UINavigationController -- MyPageViewController -- MyDetailViewController 

以下是我所做的解决方法:

在MyPageViewController.m中

 @interface MyPageViewController () <delegates> @property (strong) MyDetailViewController *initialViewController; @end - (void)viewDidLoad { ... // set this once, because we're going to use it in viewWillLayoutSubviews, // which gets called multiple times self.initialViewController = [MyDetailViewController new]; } // the problem seemed to stem from the fact that a pageViewController couldn't // properly lay out it's child view controller initially if it contained a // scroll view. by the time we're in layoutSubviews, pageViewController seems to // have gotten it's bearings and everything is laid out just fine. - (void)viewWillLayoutSubviews { [self setViewControllers:@[self.initialViewController] direction:UIPageViewControllerNavigationDirectionForward animated:false completion:nil]; } 

我也有同样的问题。 我通过在UIPageViewController的viewDidLoad中将第一页的setViewControllers放置在UIPageViewController的实例中而不是将其设置为解决scheme。 此外,我需要设置自动调整ScrollViewInsets为NO。

我有一个类似的问题,但没有解决scheme在这里工作。 我的问题是,只要我滚动到下一页,内容就会跳下来,结束在正确的位置,但开始20像素太高(显然是与状态栏有关)。 我的容器VC不是导航VC。 把头发拉出来一段时间后,最终为我工作的解决scheme只是为了确保我的内容VC中没有任何约束条件连接到顶层布局指南。 在你的情况下,这可能会也可能不可行,但是在我的情况下,这是唯一解决内容跳跃的问题。 也很奇怪,这个问题只有在过渡风格设置为滚动时才会显现出来。 只是改变页面curl使问题消失。 但我需要滚动。 希望这可以帮助别人。

尝试取消选中故事板上的这2个选项

在这里输入图像说明

尝试在故事板中selectPageViewController,并取消选中“属性”检查器中的“底部条”和“不透明条之下”。

最初我的视图控制器层次结构如下所示:

 -- UINavigationController -- MyContainerViewController -- UIPageViewController -- MyDetailViewController 

我这样设置,所以MyContainerViewController可以pipe理一个工具栏。 我把我的问题缩小到MyContainerViewController,然后它发生,我甚至不需要它,如果我inheritanceUIPageViewController。 现在我的层次结构如下所示:

 -- UINavigationController -- MyPageViewController -- MyDetailViewController 

MyPageViewControllerpipe理它的toolbar ,一切都按照预期工作,无论是在4英寸和3.5英寸的设备上。

如“Bo:”所述:将self.edgesForExtendedLayout = UIRectEdgeNone; 在MyPageViewController的viewDidLoad解决了这个问题。 – 博

这是我第一次发布在堆栈溢出,但我已经寻找解决这个问题一个多星期了。

这是我提出的一个解决scheme,我希望这适用于任何其他人有同样的问题。

我不知道你如何初始化你的详细视图控制器的框架,但我会假设你可以使用:self.view.frame.size.height;

尝试使用: self.view.frame.size.height – = self.navigationController.navigationBar.bounds.size.height;

希望这可以帮助

我看到了与iOS 9上的@Danny所描述的相同的问题。我尝试更新所有的约束条件,使它们不受约束 ,但是没有解决问题。 我最终不得不采取类似于这个黑客攻击如下:

  • 对于要显示在UIPageViewController中的每个内容页面,find最顶端的约束,即视图的顶部和顶部布局指南的底部之间的约束,并为视图控制器添加一个出口。
  • 在具有这种sockets的每个视图控制器中,为首选顶部距离添加另一个属性。 这两个网点看起来像这样(在Swift中):

     @IBOutlet weak var topGuideConstraint: NSLayoutConstraint! var topDistance: CGFloat! 
  • viewDidLoad() ,将topDistance设置为分配给故事板中约束的值:

     override func viewDidLoad() { super.viewDidLoad() topDistance = topGuideConstraint.constant } 
  • viewWillLayoutSubviews() ,确保约束具有适当的值,当topLayoutGuide.length为零时,调整状态栏的高度, 在转换过程中似乎是这种情况,而不是一旦完成:

     override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() topGuideConstraint.constant = topDistance + ( topLayoutGuide.length == 0 ? UIApplication.sharedApplication().statusBarFrame.size.height : 0 ) } 

重复显示在UIPageViewController中显示的每个内容视图控制器。 如果您还显示UINavigation栏,请根据需要调整偏移量。

这是一个不幸的手段,我讨厌这样做,但经过几个小时尝试不同的事情,我至less很高兴有一些工作,所以我可以继续前进。

由于@ djibouti33已经发布:

一个pageViewController不能正确地布局它的子视图控制器,如果它包含一个滚动视图。 当我们在layoutSubviews时,pageViewController似乎已经得到它的轴承,一切都布置得很好

通过等待layoutSubViews加载之前设置任何viewControllers到UIPageViewController是唯一的工作对我来说。

 override func viewDidLoad() { super.viewDidLoad() self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "yourPageViewController") as? UIPageViewController self.pageViewController?.dataSource = self pageViewController?.automaticallyAdjustsScrollViewInsets = false self.pageViewController?.view.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.height) self.addChildViewController(self.pageViewController!) self.view.addSubview((self.pageViewController?.view)!) self.pageViewController?.didMove(toParentViewController: self) } override func viewDidLayoutSubviews() { let startVC = self.viewControllerAtIndex(index: 0) as infoDataViewController let viewControllers = NSArray(object: startVC) self.pageViewController?.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil) } 

以上都没有为我工作

在这里我find了解决scheme

 var pageMenu : CAPSPageMenu? 

而不是像这样添加

 self.view.addSubview(pageMenu!.view) 

像下面添加您的CAPSPageMenu

 addChildViewController(pageMenu!) self.view.addSubview(pageMenu!.view) pageMenu!.didMove(toParentViewController: self) 

参考: iOS Swift:SlidingMenuView呈现imagePicker后错位

快乐编码!

Swift的djibouti33的答案(不包括不是问题解决的一部分的那一行)

Swift 3.0

 override func viewDidLoad() { super.viewDidLoad() self.automaticallyAdjustsScrollViewInsets = false }