视差效果与UIScrollView子视图

我试图在UIScrollView内的UIView上创build一个视差效果。 效果似乎有效,但不太好。

  1. 首先,我将两个UIView子视图添加到UIScrollView并设置UIScrollViews contentSize。
  2. 视图总结并创build一个contentSize {320,1000}。
  3. 然后我在scrollViewDidScroll中实现了以下内容:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat offsetY = scrollView.contentOffset.y; CGFloat percentage = offsetY / scrollView.contentSize.height; NSLog(@"percent = %f", percentage); if (offsetY < 0) { firstView.center = CGPointMake(firstView.center.x, firstView.center.y - percentage * 10); } else if (offsetY > 0){ firstView.center = CGPointMake(firstView.center.x, firstView.center.y + percentage * 10); } } 

这些代码行可以创build视差效果,但随着滚动的继续,如果我滚动到原始的起始位置,视图不会返回到原始位置。

我试图操纵视图层和框架,所有的结果。

任何帮助都感激不尽。

你的问题是,你是基于你的次要滚动的偏移比大小,而不只是在当前的偏移量。 所以当你从99的偏移量增加到100时(比如说100),你的第二个卷轴增加了10,但是当你回到99时,第二个卷轴只减less了9.9,从而不再和第二个卷轴相同这是你最后一次在99.非线性滚动是可能的,但不是你正在做的方式。

处理这个问题可能更简单的方法是创build第二个滚动视图,并将其放在实际的滚动视图下。 在主滚动setUserInteractionEnabled:false期间,使其不可变( setUserInteractionEnabled:false )并修改它的contentOffset,而不是手动移动UIImageView。

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [scrollView2 setContentOffset:CGPointMake(scrollView.contentOffset.x,scrollView.contentOffset.y * someScalingFactor) animated:NO]; } 

但是一定不要为scrollView2设置一个委托,否则你可能会得到一个循环的委托方法调用,这对你来说并不好。

比例因子是关键因素…

让我提供一个1:1的计算:

假设2个UIScrollView ,一个在前景中,另一个在后面,假设前景控制后方,并且进一步假设前景中的全宽对应于背景中的全宽,则需要应用前景比例 ,而不是前面的偏移量

 func scrollViewDidScroll(_ scrollView: UIScrollView) { let foreSpan = foreScrolView.bounds.width - foreScrolView.contentSize.width let foreRatio = scrollView.contentOffset.x / foreSpan let rearSpan = rearScrollView.bounds.width - rearScrollView.contentSize.width rearScrollView.setContentOffset( CGPoint(x: foreRatio * rearSpan, y: 0), animated: false) } 

最终效果

视差效应

前面和后面的两个滚动条都包含一个UIImageView ,以全宽显示:

 let foreImg = UIImageView.init(image: UIImage(named: "fore")) foreImg.frame = CGRect(x: 0, y: 0, width: foreImg.frame.width, height: foreScrolView.bounds.height) foreScrolView.contentSize = foreImg.frame.size foreScrolView.addSubview(foreImg) let rearImg = UIImageView.init(image: UIImage(named: "rear")) rearImg.frame = CGRect(x: 0, y: 0, width: rearImg.frame.width, height: rearScrollView.bounds.height) rearScrollView.contentSize = rearImg.frame.size rearScrollView.addSubview(rearImg) 

这将以不同的速度滚动两个图像,从边到边覆盖每个图像。


►在GitHub上find这个解决scheme和Swift Recipes的更多细节。