我正在使用 UIPageViewController
开发像滑块这样的图片库,并且在 UIPageViewController
转换样式模式下遇到了 Scroll
自动插入的问题。
这是我的布局:
UIViewController
与 UIContainerView
(洋红色背景) UIPageViewController
链接到容器(来自 #1) UIViewController(s)
列表(来自 #2),全宽高 View (1. 橙色,2. 红色,3. 绿色) 它曾经可以正常工作很长时间并且继续与 iOS 11 一起工作,除非它在具有安全区域的 iPhone X 设备上呈现:
我检查了很多不同的选项,并能够确认它与页面 Controller 的滚动模式特别相关。如果我切换到 PageCurl 过渡样式 - 它会按预期工作(全高):
页面 Controller 没有公开很多选项来控制滚动模式的这种行为,我也无法通过搜索控件树并修改各种
insets
和 frame
以及 contentSize
相关属性来“破解”它。我可以清楚地看到,一旦创建了 View Controller ,我的滚动 View contentSize
和 frame
的 34px
比容器 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
我还设置了自动布局约束以链接到 super View 而不是安全区域:
这是我的 Home Controller 代码,其余所有内容都设置在 Storyboard中(警报: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];
};
}
如何强制我的 child View Controller 具有全高(等于父容器的框架高度)?
最佳答案
我认为您可以使用代码和自定义布局来解决这个问题。我的意思是创建您的 UIPageViewController
并将其 View 插入到您的 UIViewController 代码中 而不是 Storyboard 。我觉得你
应该覆盖 UIViewController.viewDidLayoutSubviews()
并“手动”设置您的矩形(至少是 UIPageViewController 之一。)好吧,当您在代码中执行此操作时,有时您甚至不需要覆盖 UIViewController.viewDidLayoutSubviews()
因为 Apple 本身的模板没有这样做.我认为因为任何创建的 View 都有 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)
}
您可以通过扩展来扩展此功能
关于uiscrollview - 带有滚动过渡样式的 UIPageViewController 自动为 iPhone X 添加安全区域插图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48513440/