5

这不是严格意义上的编程问题,而是更多“如何完成这个”问题。

我很好奇(并且正在开发可能需要这个的应用程序)左右视差滚动是如何实现的。要确切了解我的意思,请查看 Yahoo Weather 应用程序(它是免费的 - 不用担心)。

他们是只使用一个视图控制器还是为那里显示的每个视图使用一个单独的控制器?
实现这一点的最简单方法是什么?我在这里找到了这个主题,它有点解释了它,但是他们什么时候从他们的服务器获取信息?是在视图更改时还是在应用程序启动时?

任何如何实现这种滚动的信息将不胜感激。

4

3 回答 3

5

其实很简单:

  • 子类 UIScrollView
  • 添加一个 UIView *parallaxView; 作为@property
  • 添加一个 CGFloat parallaxFactor 作为@property
  • 覆盖 layoutSubviews
  • 调用super,然后使用self.scrollOffset*parallaxFactor定位parallaxView

而已!

我自己制作了一个多功能 UIScrollView 子类,使用起来非常简单,非常适合这种情况!在 GitHub 上获取:https ://github.com/LeonardPauli/LPParallaxScrollView

祝你好运!

于 2013-07-31T19:52:40.903 回答
0

您不应该更改页面视图控制器的滚动视图的委托。它可以打破其正常行为。

相反,您可以:

  1. 向页面视图控制器的视图添加平移手势:

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panRecognized(gesture:)))
    view.addGestureRecognizer(panGesture)
    panGesture.delegate = self
    
  2. 添加新函数以了解视图是如何滚动的。

    @objc func panRecognized(gesture: UIPanGestureRecognizer) {
        // Do whatever you need with the gesture.translation(in: view)
    }
    
  3. 将您的 ViewController 声明为UIGestureRecognizerDelegate.

  4. 实现这个功能:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    
于 2020-11-09T13:55:20.460 回答
0

我基于标准 UIPageViewController 子类和视差效果的自动布局约束实现了一个小型原型。如果您想看一下,它的文档非常完整:TestParallax

简而言之,视差的核心是在scrollViewDidScroll委托方法中完成的:

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)
            }
        }
    }
}
于 2018-12-30T18:14:36.670 回答