UIPageViewController 和 AutoLayout:未正确应用约束

Posted

技术标签:

【中文标题】UIPageViewController 和 AutoLayout:未正确应用约束【英文标题】:UIPageViewController and AutoLayout: constraints are not applied correctly 【发布时间】:2014-09-01 04:21:56 【问题描述】:

我以编程方式创建了一个UIPageViewController 并将其作为子项添加到我的容器视图控制器中,如下所示:

    override func viewDidLoad() 
    super.viewDidLoad()

    self.pageViewController = UIPageViewController(transitionStyle:.PageCurl, navigationOrientation:.Horizontal, options: nil)

    self.mainImageView!.userInteractionEnabled = true

    self.pageViewController.delegate = self
    self.pageViewController.dataSource = self.modelController

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

    self.pageViewController.didMoveToParentViewController(self)

        

问题在于UIPageViewController 的视图大小不正确,如下面的视图层次结构所示。 UIPageViewController 的数据源返回的视图控制器包含一个 UIScrollView。我已经设置了UIScrollView 的约束,以便滚动视图扩展到超级视图。

在我看来,问题源于这样一个事实,即 scrollView 约束与容器视图的约束“分离”,但我不知道如何使用 StoryBoard 修复它,因为这些是不同视图中的视图 -控制器。我对以编程方式指定约束不是很熟悉,到目前为止,我以编程方式设置约束的努力都失败了。

我该如何解决这个问题,以便 UIPageViewController 的视图控制器的滚动视图正确包含在容器 ViewController 的视图中?

【问题讨论】:

【参考方案1】:

我必须以编程方式添加约束来解决问题。请注意,我无法使用 IB 添加自动布局约束,因为这里我正在处理属于 IB 中两个不同视图控制器的两个视图。这些视图以编程方式添加为子视图,因为它们是 UIPageViewController 的视图。

    override func viewDidLayoutSubviews() 
    self.pageViewController.view.setTranslatesAutoresizingMaskIntoConstraints(false)

    // Equal height constraint
    let constraint = NSLayoutConstraint(item: self.mainImageView!, attribute: .Height, relatedBy: .Equal, toItem: self.pageViewController.view, attribute: .Height, multiplier: 1.0, constant: 0)
    self.view.addConstraint(constraint)

    // Equal width constraint
    let constraint1 = NSLayoutConstraint(item: self.mainImageView!, attribute: .Width, relatedBy: .Equal, toItem: self.pageViewController.view, attribute: .Width, multiplier: 1.0, constant: 0)
    self.view.addConstraint(constraint1)

    // Equal top constraint
    let constraint2 = NSLayoutConstraint(item: self.mainImageView!, attribute: .Top, relatedBy: .Equal, toItem: self.pageViewController.view, attribute: .Top, multiplier: 1.0, constant: 0)
    self.view.addConstraint(constraint2)

    self.view.layoutSubviews()

【讨论】:

你应该调用 setNeedsLayout 而不是直接调用 layoutSubviews。 我遇到了一个奇怪的错误。 UIPageViewControllerContentView 是 UIPageViewController 用来保存您的实际内容的类。我正在以编程方式将我的视图添加到页面视图控制器。我的实际内容视图和这个 UIPageViewControllerContentView 之间有一些无法满足的约束,这导致我的滚动视图内容被剪切。 self.pageViewController.view.setTranslatesAutoresizingMaskIntoConstraints(false) 已修复。【参考方案2】:

我遇到了同样的问题,通过在viewDidLoad()添加下面的代码解决了这个问题

pageViewController!.view.setTranslatesAutoresizingMaskIntoConstraints(false)
    let views = ["pageView": pageViewController!.view]

    var constH = NSLayoutConstraint.constraintsWithVisualFormat("H:|[pageView]|", options: .AlignAllCenterY, metrics: nil, views: views)
    view.addConstraints(constH)
    var constW = NSLayoutConstraint.constraintsWithVisualFormat("V:|[pageView]|", options: .AlignAllCenterX, metrics: nil, views: views)
    view.addConstraints(constW)

我希望对某人有所帮助。

【讨论】:

以上是关于UIPageViewController 和 AutoLayout:未正确应用约束的主要内容,如果未能解决你的问题,请参考以下文章

UIStoryBoard 和 UIPageViewController 和 initWithTransitionStyle

如何在 UIPageViewController 和孩子之间正确传递对象

UIPageViewController 和 UIPageControl 透明背景颜色 - iOS

UIPageViewController 和屏幕外方向更改

UIPageViewController 和 UISwipeGestureRecognizer

UIPageViewController 滑动和点击之间的不同行为