我正在尝试在UIScrollView内的UIView上创建一个Parallax效果。 效果似乎有效,但不太好。
然后我在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);
}
}
这些代码行确实会产生视差效果,但是当滚动继续时,如果我滚动到原始起始位置,视图不会返回到原始位置。
我尝试过操作视图图层和框架,所有结果都相同。
任何帮助将不胜感激。
答案 0 :(得分:15)
您遇到的问题是您的二次滚动基于偏移量与大小的比率,而不仅仅是当前偏移量。所以当你从99的偏移量增加到100(比如说100)时,你的辅助卷轴增加10,但当你回到99时,你的辅助卷轴只会减少9.9,因此不再是这是你最后一次在99.非线性滚动是可能的,但不是你的方式。
更简单的方法是创建第二个scrollview并将其放在实际的scrollview下面。使它非难以处理(setUserInteractionEnabled:false
)并在主滚动委托期间修改它的contentOffset,而不是尝试手动移动UIImageView。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[scrollView2 setContentOffset:CGPointMake(scrollView.contentOffset.x,scrollView.contentOffset.y * someScalingFactor) animated:NO];
}
但请确保不要为scrollView2
设置委托,否则您可能会收到一个循环委托方法调用,这对您来说不会很好。
答案 1 :(得分:4)
缩放因子是关键因素......
...让我提供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上找到此解决方案,并在Swift Recipes上找到其他详细信息。