Maximilian Fuchs
Maximilian Fuchs

Reputation: 441

Animating UIScrollView rightwards

How to create an animation that moves/scrolls a seeable image section at an uniform speed rightwards? OR rather: How to animate UIScrollView rightwards?

Example: The image width is 4968 px. The image is used as a fullscreen background image. Only the first 1242px of the 4968px (image width) should be seeable at the beginning. The seeable image section should move at an uniform speed rightwards. At any time, 1242px of the image are visible. When the end of the image is reached this process should be iterated.

Visualisation of my question

Here's my code so far. It is not useful to understand what I want to accomplish because it's incomplete, but you see that I used it in the function update and so on.

override func update(_ currentTime: TimeInterval) {
    if gameStarted == true {
        enumerateChildNodes(withName: "background", using: ({
            (node, error) in

            let bg = node as! SKSpriteNode

            bg.position = CGPoint(x: bg.position.x - 2, y: bg.position.y)
            }
        }))
    }
}

Upvotes: 4

Views: 184

Answers (2)

Petro Korienev
Petro Korienev

Reputation: 4027

You don't need UIScrollView at all, if you want to have a game background moving at uniform speed.

However, to make it iterating smoothly you'll have to hold two images at the time.

var imageWidth : Float = 4968
var viewPortWidth : Float = 1242 
var velocity : Float = 10
var currentNodeIndex : Int = 0
let backgrounds : [String] = ["background0", "background1"]
var currentNodeName : String {
    get {
        return backgrounds[currentNodeIndex]
    }
}

func setup() {
    node : SKNode = SKSpriteNode(imageNamed:"backgroundImage")
    node.name = "background0"
    node1 : SKNode = SKSpriteNode(imageNamed:"backgroundImage")
    node1.name = "background1"
    addChild(node)
    addChild(node1)
    node.position = CGPoint(x: imageWidth, y: 0)
    node1.position = CGPoint(x: 0, y: 0)
}

override func update(_ currentTime: TimeInterval) {
    if gameStarted == true {
        backgrounds.forEach {
            enumerateChildNodes(withName: $0, using: {(node, error) in
                node.position = CGPoint(x: node.position.x - velocity, y: node.position.y)
            })
        }
    }
}

private func rollImageAroundIfNeeded() {
    if needsRollImages() {
        rollImagesAround()
    }
}

private func needsRollImages() -> Bool {
    node : SKNode = childNode(withName:currentNodeName)!
    return node.position.x < 2 * (screenWidth - imageWidth)
}

private func rollImageAround() {
    node : SKNode = childNode(withName:currentNodeName)!
    node.position = CGPoint(x: node.position.x + 2 * imageWidth, y: node.position.y)
    currentNodeIndex = (currentNodeIndex + 1) % 2
}

The idea is that you continuously move both images position to the left, and at some threshold "wrap" left image to the right.

Upvotes: 2

ghashi
ghashi

Reputation: 1557

You can animate its contentOffset property

@IBOutlet weak var scrollView: UIScrollView!

override func viewDidAppear(animated: Bool) {
    // This code scrolls to the point (x: 4000, y:0) in 5 seconds
    UIView.animateWithDuration(5) { [unowned self] in
        self.scrollView.contentOffset = CGPoint(x: 4000, y: 0)
    }
}

Upvotes: 2

Related Questions