【问题标题】:UIPageViewController with Scroll Transition Style automatically adds Safe Area insets for iPhone X具有滚动过渡样式的 UIPageViewController 自动为 iPhone X 添加安全区域插图
【发布时间】:2018-07-08 20:49:12
【问题描述】:

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

这是我的布局:

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

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

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

页面控制器没有提供很多选项来控制滚动模式的这种行为,我也无法通过搜索控件树和修改各种 insetsframe 来“破解”它和contentSize 相关属性。我可以清楚地看到,一旦创建了视图控制器,我的滚动视图contentSizeframe34px 小于容器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

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

这是我的 Home Controller 代码,其余的都设置在情节提要中(警告: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];
    };
}

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

【问题讨论】:

    标签: uiscrollview uipageviewcontroller uicontainerview iphone-x safearealayoutguide


    【解决方案1】:

    我认为您可以使用代码和自定义布局来解决此问题。我的意思是创建您的 UIPageViewController 并将其视图插入到您的 UIViewController 在代码中 不在情节提要上。我觉得你 应该覆盖 UIViewController.viewDidLayoutSubviews() 并“手动”设置您的矩形(至少是 UIPageViewController 之一。)好吧,当您在代码中执行此操作时,有时您甚至不需要覆盖 UIViewController.viewDidLayoutSubviews(),因为模板由苹果自己并没有这样做。我认为因为任何创建的视图都有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)
    }
    

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 2018-04-28
        • 2014-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多