水平滚动与ios的视差背景

时间:2014-09-15 12:36:46

标签: ios parallax horizontal-scrolling

我正面临着创建介绍视图的挑战,例如“Cleanio”应用程序(https://itunes.apple.com/fr/app/cleanio-pressing-la-demande/id885856031?mt=8)。
这是它的样子:
enter image description here enter image description here enter image description here


因此,背景和叠加层是独立移动的,而不是以相同的速度移动 有没有人有一个起点如何实现?

2 个答案:

答案 0 :(得分:13)

是的。

你需要的是两个UIScrollView。这些都应该是主视图的子视图(不包含在彼此中。

底部的图像包含您的图像,顶部的图像包含内容。

称呼他们imageScrollViewcontentScrollView

成为contentScrollView

的代表

内容看起来像这样......

contents:    [---page 1---][---page 2---][---page 3---][---page 4---]
image:       [------------the image------------]
screen:      [---screen---]

关键是图像小于所有页面并且大于屏幕。

滚动视图的帧宽度与屏幕相同。此图表仅用于显示内容宽度而不是帧宽。

因此,屏幕保持原样,两个滚动视图在其上移动。

现在是视差部分......

- (CGFloat)maxOffsetForScrollView:(UIScrollView *)scrollView
{
    CGFloat contentWidth = scrollView.contentSize.width;
    CGFloat frameWidth = CGRectGetWidth(scrollView.frame);

    return contentWidth - frameWidth;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    // this is the delegate method for the content scroll view.
    // I'm only doing horizontal stuff here, you can do vertical too if you want

    CGFloat maximumContentOffset = [self maximumOffsetForScrollView:self.contentScrollView];
    CGFloat currentOffset = self.contentScrollView.contentOffset.x;

    CGFloat percentageOffset = currentOffset/maximumContentOffset;

    CGFloat maximumImageOffset = [self maximumContentOffsetForScrollView:self.imageScrollView];
    CGFloat actualImageOffset = maximumImageOffset * percentageOffset;

    [self.imageScrollView setContentOffset:CGPointMake(actualImageOffset, 0)];
}

这将从内容视图中获取百分比偏移量,并将图像视图偏移相同的百分比偏移量。

结果是视差效应。您可以通过更改图像和内容的相对大小来使其更快或更慢。更多页面(或更小的图像)=更慢的视差。

答案 1 :(得分:1)

我一直在努力解决这种视差效应。如果没有@Fogmeister说明,我不会这样做,尽管我仍然需要自己弄清楚一些事情。 无论如何,这是一个Swift 2.0版本,(希望更完整):

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {


    var backgroundScrollView: UIScrollView!
    var contentScrollView: UIScrollView!
    var imageView: UIImageView!
    var contentView: UIView!
    var maxContentOffset: CGFloat!
    var maxBackgroundOffset: CGFloat!
    var cvbw: CGFloat!
    var page: Int = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        self.createBackground()
        self.createContent()
    }

    func createBackground() {
        self.imageView = UIImageView(image: UIImage(named: "ParalaxMaterial.jpg"))  //ParalaxMaterial.jpg is of size: 2500 x 2668px
        self.imageView.frame = CGRectMake(0, 0, ((self.view.bounds.height/2668) * 2500), self.view.bounds.height)
        self.backgroundScrollView = UIScrollView(frame: view.bounds)
        self.backgroundScrollView.backgroundColor = UIColor.redColor()
        self.backgroundScrollView.contentSize = imageView.bounds.size
        self.backgroundScrollView.addSubview(self.imageView)
        self.view.addSubview(self.backgroundScrollView)
        self.maxBackgroundOffset = self.maxOffsetForScrollView(self.backgroundScrollView)
    }

    func createContent() {
        self.contentView = UIView(frame: CGRectMake(0, 0, (self.view.bounds.width * 3), self.view.bounds.height))
        self.contentScrollView = UIScrollView(frame: view.bounds)
        self.contentScrollView.backgroundColor = UIColor.clearColor()
        self.contentScrollView.contentSize = self.contentView.bounds.size
        self.contentScrollView.delegate = self
        let firstButton = UIButton()
        firstButton.frame = CGRectMake(((self.contentView.bounds.width / 6) - 150), 300, 300, 100)
        firstButton.setTitle("START", forState: UIControlState.Normal)
        firstButton.titleLabel?.font = UIFont(name: "Arial", size: 18)
        firstButton.addTarget(self, action: "firstAction:", forControlEvents: UIControlEvents.TouchUpInside)
        self.contentView.addSubview(firstButton)
        let firstLabel = UILabel()
        firstLabel.frame = CGRectMake(((self.contentView.bounds.width / 6) - 100), 0, 200, 200)
        firstLabel.text = "#BrusselsLockDown"
        firstLabel.textAlignment = NSTextAlignment.Center
        self.contentView.addSubview(firstLabel)
        let secondLabel = UILabel()
        secondLabel.frame = CGRectMake(((self.contentView.bounds.width / 2) - 100), 0, 200, 200)
        secondLabel.text = "#LolCats"
        secondLabel.textAlignment = NSTextAlignment.Center
        self.contentView.addSubview(secondLabel)
        let thirdLabel = UILabel()
        thirdLabel.frame = CGRectMake((((self.contentView.bounds.width / 6) * 5) - 100), 0, 200, 200)
        thirdLabel.text = "#Final"
        thirdLabel.textAlignment = NSTextAlignment.Center
        self.contentView.addSubview(thirdLabel)
        self.contentScrollView.addSubview(self.contentView)
        self.view.addSubview(self.contentScrollView)
        self.maxContentOffset = self.maxOffsetForScrollView(self.contentScrollView)
        self.cvbw = self.contentView.bounds.width
    }

    func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
        if self.page == 1 {
            if scrollView.contentOffset.x > 0 {
                scrollView.setContentOffset(CGPointMake((self.cvbw / 3), 0), animated: true)
            }
        } else if self.page == 2 {
            if scrollView.contentOffset.x < (self.cvbw * 4/12) {
                scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
            } else if scrollView.contentOffset.x > (self.cvbw * 4/12) {
                scrollView.setContentOffset(CGPointMake(((self.cvbw / 3) * 2), 0), animated: true)
            }
        } else if self.page == 3 {
            if scrollView.contentOffset.x < (self.cvbw * 8/12) {
                scrollView.setContentOffset(CGPointMake((self.cvbw / 3), 0), animated: true)
            }
        } else {
            print("self.page messed up")
        }
    }


    func scrollViewDidScroll(scrollView: UIScrollView) {
        if scrollView == self.contentScrollView {
            let percentageOffset: CGFloat = self.contentScrollView.contentOffset.x / self.maxContentOffset
            let currentBackgroundOffsetPoint: CGPoint = CGPointMake(((self.maxBackgroundOffset * percentageOffset) + 50), 0)                self.backgroundScrollView.setContentOffset(currentBackgroundOffsetPoint, animated: false)
        }

        if self.contentScrollView.contentOffset.x == 0 {
            print("page 1")
            self.page = 1
        } else if self.contentScrollView.contentOffset.x == 320 {
            print("page 2")
            self.page = 2
        } else if self.contentScrollView.contentOffset.x == 640 {
            print("page 3")
            self.page = 3
        }
    }


    func maxOffsetForScrollView(scrollView: UIScrollView) -> CGFloat {
        let contentWidth: CGFloat = scrollView.contentSize.width - 100
        let frameWidth: CGFloat = CGRectGetWidth(scrollView.frame)
        return contentWidth - frameWidth
    }


    func firstAction (sender: UIButton) {
        print("firstAction")
        self.contentScrollView.setContentOffset(CGPointMake((self.cvbw / 3), 0), animated: true)
    }
}