Reputation:
I am trying to create an animation to create an illusion of moving object. So the object will stay at the same position but the background image view which is wider than screen width will move infinitely. The code I have doesn't work very smooth.
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.blueColor()
backgroundView.frame = CGRect(x: 0, y: 120, width: 50, height: 50)
self.view.addSubview(backgroundView)
let options = UIViewAnimationOptions.Repeat | UIViewAnimationOptions.CurveLinear
UIView.animateWithDuration(2.0, delay: 0.0, options: options, animations: {
backgroundView.frame = CGRect(x: 420, y: 120, width: 50, height: 50)
}, completion: nil)
Upvotes: 3
Views: 4110
Reputation: 3049
For Swift 5.0+, use the below function.
func animateBackground()
{
let backgroundImage = UIImage(named:"bgImage")!
// UIImageView 1
let backgroundImageView1 = UIImageView(image: backgroundImage)
backgroundImageView1.frame = CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y, width: self.view.frame.size.width, height: self.view.frame.size.height)
backgroundImageView1.contentMode = .scaleAspectFit
self.view.addSubview(backgroundImageView1)
// UIImageView 2
let backgroundImageView2 = UIImageView(image: backgroundImage)
backgroundImageView2.frame = CGRect(x: self.view.frame.size.width, y: self.view.frame.origin.y, width: self.view.frame.size.width, height: self.view.frame.height)
backgroundImageView2.contentMode = .scaleAspectFit
self.view.addSubview(backgroundImageView2)
// Animate background
UIView.animate(withDuration: 6.0, delay: 0.0, options: [.repeat, .curveLinear], animations: {
backgroundImageView1.frame = backgroundImageView1.frame.offsetBy(dx: -1 * backgroundImageView1.frame.size.width, dy: 0.0)
backgroundImageView2.frame = backgroundImageView2.frame.offsetBy(dx: -1 * backgroundImageView2.frame.size.width, dy: 0.0)
}, completion: nil)
}
Upvotes: 2
Reputation: 18878
Updated answer:
To animate a background image like you've mentioned in your comment, one way would be to create a seamless pattern for your background image and move it across the screen. For example, Move image1 across screen, follow it with image2, move image1 back to original position, move image2 back to original position, repeat. There's probably an easier way to do this depending on what you're actually going to be using this for, but this is just one example. I've made a simple background pattern for this example, feel free to use it.
func animateBackground() {
let animationOptions = UIViewAnimationOptions.Repeat | UIViewAnimationOptions.CurveLinear
let backgroundImage = UIImage(named:"backgroundPattern.jpg")!
var amountToKeepImageSquare = backgroundImage.size.height - self.view.frame.size.height
// UIImageView 1
var backgroundImageView1 = UIImageView(image: backgroundImage)
backgroundImageView1.frame = CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y, width: backgroundImage.size.width - amountToKeepImageSquare, height: self.view.frame.size.height)
self.view.addSubview(backgroundImageView1)
// UIImageView 2
var backgroundImageView2 = UIImageView(image: backgroundImage)
backgroundImageView2.frame = CGRect(x: backgroundImageView1.frame.size.width, y: self.view.frame.origin.y, width: backgroundImage.size.width - amountToKeepImageSquare, height: self.view.frame.height)
self.view.addSubview(backgroundImageView2)
// Animate background
UIView.animateWithDuration(6.0, delay: 0.0, options: animationOptions, animations: {
backgroundImageView1.frame = CGRectOffset(backgroundImageView1.frame, -1 * backgroundImageView1.frame.size.width, 0.0)
backgroundImageView2.frame = CGRectOffset(backgroundImageView2.frame, -1 * backgroundImageView2.frame.size.width, 0.0)
}, completion: nil)
// Have something in the foreground look like its moving
var square = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
square.frame.origin = CGPoint(x: self.view.frame.origin.x + 25, y: self.view.frame.size.height - 75)
square.backgroundColor = UIColor.darkGrayColor()
self.view.addSubview(square)
// Animate foreground
UIView.animateWithDuration(0.5, delay: 0, options: animationOptions, animations: {
square.transform = CGAffineTransformMakeRotation(33)
}, completion: nil)
}
You'll end up with an animation like this:
Original answer:
I'm not entirely sure what you're trying to achieve, but from what I can gather you'd like your view to not jump back to its starting position when it repeats each animation. You can achieve this by setting your UIView
's starting point off the left side of the view and its ending point off the right side of the view.
func animateSquare() {
// Create our square with size of 50x50
var square = UIView(frame: CGRect(x: 0, y: self.view.frame.height / 2, width: 50, height: 50))
// Set its origin just off the left of the screen so it is not visible
square.frame.origin = CGPoint(x: 0 - square.frame.size.width, y: self.view.frame.height / 2)
square.backgroundColor = UIColor.blackColor()
self.view.addSubview(square)
// Setup animation and repeat
let animationOptions = UIViewAnimationOptions.Repeat | UIViewAnimationOptions.CurveLinear
UIView.animateWithDuration(2.0, delay: 0, options: animationOptions, animations: {
// Offset our square's frame by the width of the view + the width of the square
// This way it moves off the screen to the right completely
square.frame = CGRectOffset(square.frame, self.view.frame.width + square.frame.width, 0.0)
}, completion: nil)
}
You'll end up with an animation like this:
Upvotes: 12