Parallax view scrolling (Yahoo weather like)

被刻印的时光 ゝ 提交于 2019-11-30 11:41:46

问题


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

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