pageViewController 上的背景图像反向重叠

background Images on pageViewController overlap in reverse

我有一个 pageViewController 显示每个索引的背景图像。从左向右(向前)滑动效果很好,但是当您向后滑动时,背景图像相互重叠。在我实现背景图片之前,每个 VC 上的 UI 正向和反向工作得很好,所以我知道它是背景图片。此外,如果我在我的 storyboard 中更改为 page curl 而不是 scroll,它在反向工作正常,只是不适用于 scroll。这显然是一个已知错误 (Removing a view controller from UIPageViewController),但我需要 Swift 中的解决方案。

pageviewController:

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

        guard
            let currentPageViewController = viewController as? SinglePageViewController,
            let currentIndex = indexOfForecast(currentPageViewController.forecast!) as? Int where currentIndex != 0 else { return nil }  //fixed bug where index was -0 only on scroll

        return viewControllerAtIndex(currentIndex - 1)

    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        guard
            let lastForecast = forecasts?.last,
            let currentPageViewController = viewController as? SinglePageViewController, currentForecast = currentPageViewController.forecast,
            let currentIndex = indexOfForecast(currentForecast) as? Int where currentIndex != forecasts?.indexOf(lastForecast) else {return nil}

            return viewControllerAtIndex(currentIndex + 1)

    }

 func viewControllerAtIndex(index: Int) -> UIViewController? {
        if let forecast = forecasts?[index] {
            let time = forecastTimes[index]
            let imageURL = conditionsIcons[index]
            let backgroundImageName = backgroundImageNames.names[index]
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewControllerWithIdentifier("SinglePageViewController") as! SinglePageViewController
            vc.forecast = forecast
            vc.time = time
            vc.imageURL = imageURL
            vc.backgroundImageName = backgroundImageName

            return vc
        }
        return nil
    }


    func showVC() {
        if let firstVC = viewControllerAtIndex(0) {
            busyAlertController.dismiss()
            let viewControllers = [firstVC]
            self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
        }
    }

单页视图控制器:

override func viewDidLoad() {
        super.viewDidLoad()

        backgroundImage = UIImageView(image: UIImage(named: backgroundImageName!))
        backgroundImage.contentMode = UIViewContentMode.ScaleAspectFill
        self.view.insertSubview(backgroundImage, atIndex: 0)
}

根据我的回答 over here,这里有一个 Swift 版本。请注意,这是使用在线转换器从 Objective-C 转换为 Swift 的(因为我不在我的开发机器上——并且通常不在 Swift 中工作),并添加了一些摆弄获得弱自引用权。请随时指出实施中的任何错误。

pageViewController.setViewControllers(
    viewControllers, 
    direction: UIPageViewControllerNavigationDirectionForward, 
    animated: true, 
    completion: { [weak pageViewController] (finished: Bool) in 
        if finished {
            dispatch_async(dispatch_get_main_queue(), {                            
                pageViewController.setViewControllers(
                    viewControllers, 
                    direction: UIPageViewControllerNavigationDirectionForward, 
                    animated: false, 
                    completion: nil
                )

        })
    }

})

使用 [weak ...] 的技巧称为 "Capture List",在 this question, as well as the official docs 部分 "Defining a Capture List" 中有很好的介绍。

(如果你没有跟踪这个,我们的意图是我们不希望我们的闭包对 pageViewController 有强引用,因此如果它是不再需要。所以我们将该变量标记为弱引用,如果闭包是最后留下对 pageViewController 的引用的东西,sayon​​ara).

另一点是,我没有注意可选方面的东西,所以请注意实现者。


编辑:

看你的代码,我的回答根本不是你想要的。我的回答解决的问题是以编程方式设置视图控制器,但你说的是滑动。

我猜你还没有实现所有的委托方法——我只看到 viewControllerAtIndex。难道不需要 viewControllerBeforeViewControllerviewControllerAfterViewController 才能正常工作吗? (抱歉,我已经有一段时间没处理那个了 class。)粗略浏览 this tutorial 让我这么想......

总之,我认为是找错树了。请检查一下,并可能详细说明您的问题,显示更多代码等。

这个问题的答案很简单,只需将图像上的 clipsToBounds 设置为 true

除了@GarySabo 的回答之外,我还必须将图像的约束布局到超级视图(在我的例子中是默认视图),如下所示: