带有Scroll Transition Style的UIPageViewController会自动为iPhone X添加安全区域插入

时间:2018-01-30 03:28:45

标签: uiscrollview uipageviewcontroller uicontainerview iphone-x safearealayoutguide

我正在使用UIPageViewController开发像滑块这样的图片库,我在UIPageViewController转换样式模式下遇到Scroll自动插件的麻烦。

这是我的布局:

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

    它曾经很好地工作了很长时间并继续使用iOS 11,除非它在具有安全区域的iPhone X设备上呈现:

    enter image description here

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

    enter image description here

    页面控制器没有公开很多选项来控制滚动模式的这种行为,我也无法通过搜索控件树并修改各种insets和{来“破解”它。 {1}}和frame相关的属性。我可以清楚地看到,创建视图控制器后,我的滚动视图contentSizecontentSizeframe34pxframe

    > 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
    

    我还设置了自动布局约束以链接到superview而不是安全区域:

    enter image description here

    以下是我的家庭控制器代码,所有其余内容都在故事板中设置(警告: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];
        };
    }
    

    如何强制我的孩子查看控制器的高度(等于父容器的框架高度)?

2 个答案:

答案 0 :(得分:0)

我认为您可以使用代码和自定义布局解决此问题。我的意思是创建您的UIPageViewController并将其视图插入代码中的UIViewController 而不是故事板。我觉得你 应该覆盖UIViewController.viewDidLayoutSubviews()并“手动”设置你的rects(至少是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)
}

您可以通过扩展

来扩展此功能

答案 1 :(得分:0)

我有一个类似的问题,只发生在X尺寸上,经过数小时的曲折和错误后,我将其修复。

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

因此,要解决此问题,我必须将图像设置为Aspect Fit或.py。我之所以使用后者,是因为它对UI更好。