Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIScrollView子视图的视差效果_Ios_Objective C_Uiview_Uiscrollview_Parallax - Fatal编程技术网

Ios UIScrollView子视图的视差效果

Ios UIScrollView子视图的视差效果,ios,objective-c,uiview,uiscrollview,parallax,Ios,Objective C,Uiview,Uiscrollview,Parallax,我试图在UIScrollView中的UIView上创建视差效果。 这种效果似乎有效,但效果不太好 首先,我将两个UIView子视图添加到UIScrollView,并设置UIScrollViews contentSize 视图汇总并创建一个contentSize{3201000} 然后,我在scrollViewDidScroll中实现了以下功能: - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat offsetY

我试图在UIScrollView中的UIView上创建视差效果。 这种效果似乎有效,但效果不太好

  • 首先,我将两个UIView子视图添加到UIScrollView,并设置UIScrollViews contentSize
  • 视图汇总并创建一个contentSize{3201000}
  • 然后,我在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);
    
        }
    }
    
    -(无效)scrollViewDidScroll:(UIScrollView*)scrollView
    {
    CGFloat offsetY=scrollView.contentOffset.y;
    CGFloat percentage=offsetY/scrollView.contentSize.height;
    NSLog(@“百分比=%f”,百分比);
    如果(偏移量<0){
    firstView.center=CGPointMake(firstView.center.x,firstView.center.y-百分比*10);
    }否则如果(偏移量>0){
    firstView.center=CGPointMake(firstView.center.x,firstView.center.y+百分比*10);
    }
    }
    
  • 这些代码行确实创建了视差效果,但随着滚动的继续,如果我滚动到原始起始位置,视图不会返回到其原始位置

    我尝试过操纵视图层和框架,所有这些都得到了相同的结果


    任何帮助都将不胜感激

    问题在于,您的第二次滚动是基于偏移量与大小的比率,而不仅仅是基于当前偏移量。因此,当你从偏移量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: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)
    
    这将以不同的速度滚动两幅图像,从边缘到边缘完全覆盖每幅图像



    ► 在上找到此解决方案,并在上找到其他详细信息。

    条件金额为百分比=晶圆厂(百分比);,这似乎是错误的。当您仅用else块替换条件时,效果如何?我还没有尝试过这一点,因此没有答案,但这段代码对我来说更有希望:@danh,如果我向下滚动时,将“if”替换为“else”(offset=-x)视图将慢慢反弹。我在我的答案中添加了一个编辑,以从数字上解释您的问题存在的原因。与github ref类似,但更简单+1。确保scrollView2的内容包含前景视图的反弹区域。@danh反弹对创建者来说是一个练习,但肯定是的。我发现iPad上可能出现的反弹量是屏幕宽度或高度的37%,仅供参考。@Putz1103谢谢你的回答。当你说把scrollView2放在实际的scrollview下面时,你的意思是给它一个Z索引吗?@Raz不,只要把它放在你的视图层次结构中你想要的任何位置就行了。您可以在UIView中使用
    将SubViewToFront
    发送SubViewToBack
    来获得您想要的最终结果。@Putz1103,很好的解决方案。谢谢!