user3832583
user3832583

Reputation: 371

How to make a view scroll against a scrollview animation?

So I have a UIView and I want to have it animate a translation in the opposite direction of the scrollviews scroll animation. How would I go about doing this? Of course this should be depend on the scrollview.contentOffset I think anyway. So if you scroll the other way it goes back to it's place. So the translation is dependent on how far the user scrolls. I am trying to use the following code. Also note that the UIView I currently do not have as a child of the scrollview. It is suppose to stay on screen at all time, but change positions.

func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.x >= scrollView.contentSize.width {
    UIView.animate(withDuration: 2.0, animations: {
        self.view.layoutIfNeeded()
    })
}

enter image description here

Upvotes: 1

Views: 2206

Answers (1)

Scriptable
Scriptable

Reputation: 19758

A simple solution would be:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    let percentage = scrollView.contentOffset.x / scrollView.contentSize.width
    self.box.frame.origin.x = UIScreen.main.bounds.width * percentage
}

Just calculate the percentage of the contentSize that you have scrolled and set the X position to the same percentage of the screen width.

It could do with some improvements to make sure the view doesn't go beyond the bounds of the screen in certain conditions. So you may need to factor in the width of the box in the calculations as an enhancement.

Here is the code I used for testing, The background image is a 4K wallpaper image.

class ViewController: UIViewController {

    var box = UIView()
    var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.scrollView = UIScrollView()
        self.scrollView.translatesAutoresizingMaskIntoConstraints = false
        self.scrollView.delegate = self
        self.view.addSubview(self.scrollView)

        NSLayoutConstraint(item: scrollView, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: scrollView, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: scrollView, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: scrollView, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true


        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.image = UIImage(named: "background")
        self.scrollView.addSubview(imageView)

        NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: imageView, attribute: .left, relatedBy: .equal, toItem: scrollView, attribute: .left, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: imageView, attribute: .right, relatedBy: .equal, toItem: scrollView, attribute: .right, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: imageView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true

        box.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - 110, width: 100, height: 100)
        box.backgroundColor = .black
        self.view.addSubview(box)
    }
}

extension ViewController: UIScrollViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        let percentage = scrollView.contentOffset.x / scrollView.contentSize.width
        let xPosition = UIScreen.main.bounds.width * percentage

        self.box.frame.origin.x = xPosition
    }
}

Upvotes: 1

Related Questions