问题
This is not strictly a programming question but more "how to accomplish this" question.
I am curious (and working on an app that will probably require this) how is left-right parallax scrolling implemented. To know exactly what I mean check the Yahoo Weather app (it's free - no worries there).
Are they using just one view controller or a separate controller for each view that is shown there?
What is the easiest way to implement this? I have found this topic here which kinda explains it a bit but when are they getting information from their servers? Is it when the views are changed or at the startup of the app?
Any information how to implement such scrolling would be much appreciated.
回答1:
It's really simple actually:
- Subclass UIScrollView
- Add a UIView *parallaxView; as @property
- Add a CGFloat parallaxFactor as @property
- Override layoutSubviews
- Call super, and then use self.scrollOffset*parallaxFactor to position the parallaxView
That's it!
I've made a multifunctional UIScrollView subclass myself that's really simple to use, perfect for this case! Get it on GitHub: https://github.com/LeonardPauli/LPParallaxScrollView
Good Luck!
回答2:
I implemented a small prototype based on a standard UIPageViewController subclass, and autolayout constraints for the parallax effect. It's quite fully documented, if you want to have a look : TestParallax
In a nutshell, the heart of the parallax is done in the scrollViewDidScroll
delegate method:
extension PageViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let screenWidth = scrollView.bounds.width
/*
In a UIPageViewController, the initial contentOffset.x is not 0, but equal to the screen width
(so that the offset goes between (1 * screenWidth) and 0 when going to the previous view controller,
and from (1 * screenWidth) to (2 * screenWidth) when going to the next view controller).
Also, it's reset to the screenWidth when the scroll to a previous or next view controller is complete.
Therefore, we calculate a new 'horizontalOffset' starting at 0, and going:
- negative from 0 to (-screenWidth/2) when scrolling to the next view controller,
- and from 0 to (screenWidth/2) when scrolling to the previous view controller.
*/
let horizontalOffset = (scrollView.contentOffset.x - screenWidth)/2
// Special case: initial situation, or when the horizontalOffset is reset to 0 by the UIPageViewController.
guard horizontalOffset != 0 else {
previousPageController?.offsetBackgroundImage(by: screenWidth/2)
currentPageController?.offsetBackgroundImage(by: 0)
nextPageController?.offsetBackgroundImage(by: -screenWidth/2)
return
}
// The background image of the current page controller should always be offset by the horizontalOffset (which may be positive or negative)
guard let currentPageController = currentPageController else { return }
currentPageController.offsetBackgroundImage(by: horizontalOffset)
if horizontalOffset > 0 { // swiping left, to the next page controller
// The background image of the next page controller starts with an initial offset of (-screenWidth/2), then we apply the (positive) horizontalOffset
if let nextPageController = nextPageController {
let nextOffset = -screenWidth/2 + horizontalOffset
nextPageController.offsetBackgroundImage(by: nextOffset)
}
} else { // swiping right, to the previous page controller
// The background image of the previous page controller starts with an initial offset of (+screenWidth/2), then we apply the (negative) horizontalOffset
if let previousPageController = previousPageController {
let previousOffset = screenWidth/2 + horizontalOffset
previousPageController.offsetBackgroundImage(by: previousOffset)
}
}
}
}
来源:https://stackoverflow.com/questions/17979549/parallax-view-scrolling-yahoo-weather-like