问题
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