防止刷UIPageViewController时出现的白色间隙

时间:2015-03-22 18:27:21

标签: ios iphone swift uiimageview uipageviewcontroller

我已经以这种方式实现了UIPageViewController:

Screenshot1

GalleryViewController:是PageViewController的容器

PageViewController:是pageViewController,我将它作为子视图添加到GalleryViewController。

PageContentViewController:我把它放在UIImageView中作为页面视图控制器的内容。

一切进展顺利,但是当我在图像之间滑动时,会发生奇怪的事情。白色差距出现上升。

white gap

奇怪的是,当我完成滚动时,它会自动拉伸。

full screen

这是GalleryViewController的代码,它是PageViewController的容器:

import UIKit

class PageViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

var startIndex:Int = 0

var pageViewController : UIPageViewController!

override func viewDidLoad() {
    self.navigationController?.hidesBarsOnTap = true;
    reset()
}

func reset() {
    /* Getting the page View controller */
    pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as UIPageViewController
    self.pageViewController.dataSource = self

    let pageContentViewController = self.viewControllerAtIndex(0)
    self.pageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)

    self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
    self.addChildViewController(pageViewController)
    self.view.addSubview(pageViewController.view)
    self.pageViewController.didMoveToParentViewController(self)
    println("\(startIndex) start index")
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {

    var index = (viewController as PageContentViewController).pageIndex!
    index++
    if(index >= Constants.Statics.images.count){
        return nil
    }
    return self.viewControllerAtIndex(index)

}

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {

    var index = (viewController as PageContentViewController).pageIndex!
    if(index <= 0){
        return nil
    }
    index--
    return self.viewControllerAtIndex(index)

}

func viewControllerAtIndex(index : Int) -> UIViewController? {
    if((Constants.Statics.images.count == 0) || (index >= Constants.Statics.images.count)) {
        return nil
    }
    let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageContentViewController") as PageContentViewController
    pageContentViewController.pageIndex = index
    return pageContentViewController
}

}

我可以做些什么来防止拉伸时的拉伸和白色间隙?

更新:

发生了一件奇怪的事情,我将pageViewController Transition Style更改为Page Curl,问题没有出现。听起来像是关于滚动!

7 个答案:

答案 0 :(得分:4)

错误的起源是UIImageView的约束。

当您开始滚动时,仅调用viewWillAppear,并且尚未计算autolayout,滚动完成后显示视图,视图开始计算autolayout,并且在autolayout完成后发生viewDidAppear。

您可以在PageContentViewController

中添加以下代码来检查
  override func viewDidLoad() {
    super.viewDidLoad()

    imageView.image = UIImage(named: "UpcomingGamesBg")
    println("viewDidLoad imageView Frame : \(imageView.frame) pageIndex : \(pageIndex)")
  }

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    println("viewWillAppear imageView Frame : \(imageView.frame) pageIndex : \(pageIndex)")
  }

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    println("viewDidAppear imageView Frame : \(imageView.frame) pageIndex : \(pageIndex)")
  }

因为,imageView的布局参考顶部布局指南,并且顶部布局指南在计算自动布局之前和之后可以有不同的值,你有这个错误。

因此,为了解决这个问题,您可以更改图像视图的约束并使它们成为父视图的亲戚(因为pageContentViewController就像一个子视图,而pagerViewController将管理顶部和底部边距),如下所示:

enter image description here

enter image description here enter image description here

有了这个你可以修复这个bug,但要小心你应该为你的pageViewController.view添加一些约束

<强>更新

例如,要支持navigationBar / TabBar,您应该在viewDidLoad中添加一些约束(在view.addSubview(pageViewController.view)之后):

      pageViewController.view.setTranslatesAutoresizingMaskIntoConstraints(false)

    let topConstraint = NSLayoutConstraint(item: pageViewController.view, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: topLayoutGuide, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0)
    let bottomConstaint = NSLayoutConstraint(item: pageViewController.view, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: bottomLayoutGuide, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0)
    let leadingConstraint = NSLayoutConstraint(item: pageViewController.view, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 0)
    let trailingConstraint = NSLayoutConstraint(item: pageViewController.view, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 0)

    view.addConstraints([topConstraint, bottomConstaint, leadingConstraint, trailingConstraint])

致以最诚挚的问候,

答案 1 :(得分:2)

自动拉伸是因为ImageView实例不受约束方面的限制。在PageContentViewController中,为图片指定contentMode值以解决问题。例如:

self.imageView.contentMode = UIViewContentModeScaleAspectFit

答案 2 :(得分:2)

请在此处查看明确示例:https://github.com/dimpiax/UIPageViewControllerScrolling

但是如果要在滑动时删除空白,可以删除反弹,例如:

for value in view.subviews {
    if let scrollView = value as? UIScrollView {
        scrollView.bounces = false
    }
}

答案 3 :(得分:1)

因此,在动画发生之前,视图的框架似乎不正确。尝试在帧开始出现之前设置帧。类似的东西:

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {

    var index = (viewController as PageContentViewController).pageIndex!
    if(index <= 0){
        return nil
    }
    index--

    // Setting up the new view's frame
    var newVC = self.viewControllerAtIndex(index)
    newVC.view.frame = self.pageViewController.view.bounds
    return newVC
}

答案 4 :(得分:1)

你试过那些吗?您应首先选择内容视图控制器。注意:单击控制器,而不是视图

  1. 取消选中“调整滚动视图插图”
  2. 取消选中Top Top Bars
  3. 取消选中Under Bottom Bars
  4. enter image description here

答案 5 :(得分:1)

看起来像布局问题。

由于UIPageViewController .Scroll类型使用UIScrollView来制作它,

尝试将self.automaticallyAdjustsScrollViewInsets = false添加到您的viewDidLoad

如果不起作用,请尝试删除self.navigationController?.hidesBarsOnTap = true

如果它再次不起作用,请提供一个演示项目,这样我就可以找出问题所在。

答案 6 :(得分:0)

将imageView的contentMode设置为AspectFill ...