4

我正在使用滑块开发图像库,但在过渡样式模式下自动插入时UIPageViewController遇到问题。UIPageViewControllerScroll

这是我的布局:

  1. UIViewControllerUIContainerView(洋红色背景)
  2. UIPageViewController链接到容器(来自 #1)
  3. 页面控制器中动态创建UIViewController(s)的视图列表(来自 #2),全宽高视图(1.橙色,2.红色,3.绿色)

在此处输入图像描述

它曾经可以正常工作很长时间并继续与 iOS 11 一起工作,除非它在具有安全区域的 iPhone X 设备上呈现:

在此处输入图像描述

我检查了很多不同的选项,并且能够确认它与页面控制器的滚动模式特别相关。如果我切换到 PageCurl 过渡样式 - 它按预期工作(全高):

在此处输入图像描述

页面控制器没有公开很多选项来控制滚动模式的这种行为,我也无法通过搜索控件树和修改各种相关属性来“破解insets”它framecontentSize我可以清楚地看到,一旦创建了视图控制器,我的滚动视图contentSize就会frame34px容器小frame

> view.frame
{{X=0,Y=0,Width=375,Height=732}}
    Bottom: 732
    Height: 732
    IsEmpty: false
    Left: 0
    Location: {{X=0, Y=0}}
    Right: 375
    Size: {{Width=375, Height=732}}
    Top: 0
    Width: 375
    X: 0
    Y: 0

> scroll.frame
{{X=-5,Y=0,Width=385,Height=698}}
    Bottom: 698
    Height: 698
    IsEmpty: false
    Left: -5
    Location: {{X=-5, Y=0}}
    Right: 380
    Size: {{Width=385, Height=698}}
    Top: 0
    Width: 385
    X: -5
    Y: 0

> scroll.contentSize
{{Width=1155, Height=698}}
    Height: 698
    IsEmpty: false
    Width: 1155

我还设置了我的自动布局约束以链接到超级视图而不是安全区域:

在此处输入图像描述

这是我的家庭控制器代码,其余的都设置在情节提要中(警告:C# Xamarin 语法)

private List<UIViewController> viewControllers;

public HomePageViewController (IntPtr handle) : base ( handle)
{
}

public override void ViewDidLoad()
{
    base.ViewDidLoad();
    var child1 = new UIViewController();
    child1.View.BackgroundColor = UIColor.Orange;
    var child2 = new UIViewController();
    child2.View.BackgroundColor = UIColor.Red;
    var child3 = new UIViewController();
    child3.View.BackgroundColor = UIColor.Green;

    this.viewControllers = new List<UIViewController>
    {
        child1,
        child2,
        child3,
    };

    this.SetViewControllers(new UIViewController[] { child1 }, UIPageViewControllerNavigationDirection.Forward, false, null);

    this.GetNextViewController = (c, r) =>
    {
        var current = this.viewControllers.IndexOf(this.ViewControllers[0]);
        if (current >= this.viewControllers.Count - 1)
            return null;

        return this.viewControllers[current + 1];
    };

    this.GetPreviousViewController = (c, r) =>
    {
        var current = this.viewControllers.IndexOf(this.ViewControllers[0]);
        if (current <= 0)
            return null;

        return this.viewControllers[current - 1];
    };
}

如何强制我的子视图控制器具有全高(等于父容器的框架高度)?

4

3 回答 3

0

我有一个类似的问题,只发生在 X 尺寸中,经过数小时的跟踪和错误,我得到了修复。

我不确定它是否适用于您,但我拥有页面视图控制器 VC 的方式是每个 VC 都有一个图像填充其背景。我有 3 页。第一次滚动看起来很正常,但是当我从第 2 页到第 1 页或从第 1 页到第 0 页反向滚动时,第 1 页的图像会在应该完全隐藏时从侧面显示大约 40 像素(类似于您的屏幕截图)。

所以要修复它,我必须将图像设置为 Aspect Fit 或clips to bounds = true. 我使用后者是因为它更适合 UI。

于 2018-09-23T12:05:15.300 回答
0

我认为您可以使用代码和自定义布局来解决此问题。我的意思是创建您UIPageViewController的视图并将其视图插入到您的 UIViewController中, 而不是在 storyboard 上。我认为您应该UIViewController.viewDidLayoutSubviews()“手动”覆盖并设置您的矩形(至少是 UIPageViewController 之一。)好吧,当您在代码中执行此操作时,有时您甚至不需要覆盖UIViewController.viewDidLayoutSubviews(),因为 Apple 本身的模板没有这样做这个。我认为因为任何创建的视图都有translatesAutoresizingMaskIntoConstraints = true。所以你也可以遵循这种方法。

当您创建一个新项目并将其声明为page based app.

如果需要,这是模板(警告:这是 Apple 自己模板的一部分)

    var pageViewController: UIPageViewController?


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    // Configure the page view controller and add it as a child view controller.
    self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    self.pageViewController!.delegate = self

    let startingViewController: DataViewController = self.modelController.viewControllerAtIndex(0, storyboard: self.storyboard!)!
    let viewControllers = [startingViewController]
    self.pageViewController!.setViewControllers(viewControllers, direction: .forward, animated: false, completion: {done in })

    self.pageViewController!.dataSource = self.modelController

    self.addChildViewController(self.pageViewController!)
    self.view.addSubview(self.pageViewController!.view)

    // Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
    var pageViewRect = self.view.bounds
    if UIDevice.current.userInterfaceIdiom == .pad {
        pageViewRect = pageViewRect.insetBy(dx: 40.0, dy: 40.0)
    }
    self.pageViewController!.view.frame = pageViewRect

    self.pageViewController!.didMove(toParentViewController: self)
}

您可以通过扩展来扩展此功能

于 2018-02-09T04:21:11.867 回答
0

UIPageViewController使用以下代码实现了全屏高度显示:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    guard let contentScrollView = view.subviews.first(where: { $0 is UIScrollView }) else { return }
    contentScrollView.frame.size.height = view.frame.height
}
于 2022-02-01T16:03:43.077 回答