background Images on pageViewController overlap in reverse

╄→尐↘猪︶ㄣ 提交于 2019-12-21 17:51:50

问题


I have a pageViewController that shows a background image per the index. It works fine swiping left to right (forward), but when you swipe in reverse the background images overlap each other. Before I implemented the background image, the UI on each VC worked fine forward and reverse, so I know it's the background image. Also if I change to page curl instead of scroll in my storyboard it works fine in reverse, just doesn't work for scroll. This apparently is a known bug (Removing a view controller from UIPageViewController) however I need a solution in 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)
        }
    }

singlePageViewController:

override func viewDidLoad() {
        super.viewDidLoad()

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

回答1:


The answer to this problem was so simple, just set clipsToBounds on the image to true




回答2:


Based on my answer over here, here is a Swift version. Note that this was converted from Objective-C to Swift using an online converter (as I am not at my dev machine--and don't usually work in Swift) with some added fiddling to get the weak self reference right. Feel free to point out any mistakes in implementation.

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
                )

        })
    }

})

The trick with [weak ...] is called a "Capture List" and is covered nicely in this question, as well as the official docs, section "Defining a Capture List".

(The intention, in case you weren't tracking with this, is that we don't want our closure to have a strong reference to the pageViewController, and thus prevent ARC from deallocating it if it's no longer needed. So we mark that variable as being a weak reference, and if the closure is the last thing left with a reference to the pageViewController, sayonara).

Another point is, I haven't paid any attention to the optionals aspect of things, so caveat implementor.


EDIT:

Looking at your code, it doesn't look like my answer is what you want, at all. The issue that my answer addresses is programatically setting the view controller, but you're talking about swiping.

My guess is that you haven't implemented all of the delegate methods--I only see viewControllerAtIndex. Doesn't one have to do viewControllerBeforeViewController and viewControllerAfterViewController for the thing to work properly? (Sorry, it's been a while since I dealt with that class.) A cursory glance at this tutorial makes me think so...

Anyway, methinks that barking up the wrong tree has occurred. Please check this out, and maybe elaborate on your question, show more code, etc.




回答3:


In addition to @GarySabo's answer I had to layout the image's constraints to the superview (in my case the default view) like so:



来源:https://stackoverflow.com/questions/33742522/background-images-on-pageviewcontroller-overlap-in-reverse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!