Swift Image Rotation showing 50% image - ios

I'm new in swift and iPhone development. Recently I'm working on a topic where I have to rotate the image vertically.
I've almost solved the issue but problem is my image is rotating but while it's rotating it's showing 50% image. Here is the link of the issue in video. http://screencast.com/t/VI4yZ0a8Wr
Also here the code i'm using
func animationRotationEffect(view:UIView,animationTime:Float)
{
UIView.animateWithDuration(NSTimeInterval(animationTime), animations: { () -> Void in
/* previously used
same result produced as below
var animation:CABasicAnimation = CABasicAnimation(keyPath: "transform")
animation.toValue = NSValue(CATransform3D:CATransform3DMakeRotation(CGFloat(M_PI), 1, 0, 0))
animation.duration = CFTimeInterval(animationTime)
animation.cumulative = false
animation.repeatCount = 1
view.layer.addAnimation(animation, forKey: nil)
*/
let animate = CABasicAnimation(keyPath: "transform.rotation.x")
animate.duration = CFTimeInterval(animationTime)
animate.repeatCount = Float.infinity
animate.fromValue = 0.0
animate.toValue = Float(M_PI * 2.0)
view.layer.addAnimation(animate, forKey: nil)
})
}
It would be very helpful if anyone can help me on this.
Thanks in advance,
Nixon

Maybe it's not an animation problem, try setting the aspect and content mode of your UIImageView to this
imageView.contentMode = UIViewContentMode.ScaleAspectFit
More info about UIViewContentMode enumeration here

Related

Spring animation for rotation that ends where it began

I'd like to create a CASpringAnimation for rotation that ends where it began. Here's some working code that doesn't end where it began (but otherwise is what I'm looking for):
func spring(view: UIView) -> CASpringAnimation{
let animation = CASpringAnimation(keyPath: "transform")
animation.damping = 0.5
animation.initialVelocity = 70
animation.mass = 0.04
animation.stiffness = 12
animation.duration = 1.2
animation.toValue = CATransform3DRotate(CATransform3DMakeAffineTransform(view.transform),
CGFloat(M_PI)/32, // Must be non-zero 😕
0, 0, 1)
return animation
}
And here's how you'd use it:
let animation = spring(view: viewToAnimate)
viewToAnimate.layer.add(animation, forKey: nil)
When I set the angle (beside the comment in CATransform3DRotate) to 0, the animation doesn't work! Any ideas on how to get a spring rotation with the same start and end angles? Thanks for reading.
By adding a CABasicAnimation that animates to 0° over the same time duration, and also by tweaking the spring animation parameters, I've got something that looks pretty good (tested for iOS 10):
#IBAction func springButtonTapped(_ sender: UIButton) { // Attach to the view you'd like animated
let springAnim = spring(view:sender)
sender.layer.add(springAnim, forKey: nil)
let correctionAnim = correct(view:sender)
sender.layer.add(correctionAnim, forKey: nil)
}
func correct(view: UIButton) -> CABasicAnimation{
let animation = CABasicAnimation(keyPath: "transform")
animation.duration = 0.3
animation.toValue = CATransform3DRotate(CATransform3DMakeAffineTransform(view.transform),
0,
0, 0, 1)
return animation
}
func spring(view: UIView) -> CASpringAnimation{
let animation = CASpringAnimation(keyPath: "transform")
animation.damping = 0.0
animation.initialVelocity = 80
animation.mass = 0.04
animation.stiffness = 50
animation.duration = 0.3
animation.toValue = CATransform3DRotate(CATransform3DMakeAffineTransform(view.transform),
CGFloat(M_PI)/64,
0, 0, 1)
return animation
}

Turn rectangular UIImageView into a circle

My ViewController has an UIImageView (lets name it img) as atribute, and in the beginning, it shows img in full screen, that is, its size is a rectangle similar to the ViewController bounds.
I'd like to do an animation with img, making it become a little circle (not just a rectangle with circular corners) and then move it to some corner of the ViewController.
How can I achieve this? I prefer not to send any code cos Im pretty sure I did it the wrong way (I tried to turn it into a square and then set a cornerRadius (with radius width/2), then making scale and translating position at once, but its a mess and works wrongly, so lets forget it)
Your solution sounds fine to me, but what might be going wrong, is the fact that animating corner radius is not supported by UIView.animateWithDuration as seen in the View Programming Guide for iOS. Therefor, the results are sometimes not whats expected.
You can try out the following code.
func animate() {
//Some properties that needs to be set on UIImageView
self.imageView.clipsToBounds = true
self.imageView.contentMode = .ScaleAspectFill
//Create animations
let cornerRadiusAnim = changeCornerRadiusAnimation()
let squareAnim = makeSquareAnimation()
let boundsAnim = changeBoundsAnimation()
let positionAnim = changePositionAnimation(CGPointMake(300,480))
//Use group for sequenced execution of animations
let animationGroup = CAAnimationGroup()
animationGroup.animations = [cornerRadiusAnim, squareAnim, boundsAnim, positionAnim]
animationGroup.fillMode = kCAFillModeForwards
animationGroup.removedOnCompletion = false
animationGroup.duration = positionAnim.beginTime + positionAnim.duration
imageView.layer.addAnimation(animationGroup, forKey: nil)
}
func makeSquareAnimation() -> CABasicAnimation {
let center = imageView.center
let animation = CABasicAnimation(keyPath:"bounds")
animation.duration = 0.1;
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.fromValue = NSValue(CGRect: imageView.frame)
animation.toValue = NSValue(CGRect: CGRectMake(center.x,center.y,imageView.frame.width,imageView.frame.width))
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
return animation
}
func changeBoundsAnimation() -> CABasicAnimation {
let animation = CABasicAnimation(keyPath:"transform.scale")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.fromValue = imageView.layer.mask?.valueForKeyPath("transform.scale")
animation.toValue = 0.1
animation.duration = 0.5
animation.beginTime = 0.1
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
return animation
}
func changeCornerRadiusAnimation() -> CABasicAnimation {
let animation = CABasicAnimation(keyPath:"cornerRadius")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.fromValue = 0
animation.toValue = imageView.frame.size.width * 0.5
animation.duration = 0.1
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
return animation
}
func changePositionAnimation(newPosition: CGPoint) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = NSValue(CGPoint: imageView.layer.position)
animation.toValue = NSValue(CGPoint: newPosition)
animation.duration = 0.3
animation.beginTime = 0.6
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
return animation
}
// try like this, i hope it will work for you.
UIView.animateWithDuration(3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in
img.layer.masksToBounds = true
img.layer.cornerRadius = img.frame.size.height / 2 // here img must be in square shape (height == width)
}) { (finished : Bool) -> Void in
}
option 1 call below method from code
// UIimageView Circle
class func roundImageView(imageView:UIImageView){
imageView.layer.borderWidth = 1.0
imageView.layer.masksToBounds = false
//imageView.layer.borderColor = UIColor.whiteColor().CGColor
imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true
}
option 2 make user defined run time attributes from storyboard
view.layer.cornerRadius = 5.0f;
view.layer.masksToBounds = NO;

Spinning objects in iOS

How do I make an object, for example an image, rotate forever?
UIView.animateWithDuration(2.0, animations: ({
self.Cube.transform = CGAffineTransformMakeRotation(320)
}))
Does anyone have a solution, would really appreciate some help.
Try this function to rotate a layer forever.
func rotateLayer(layer:CALayer,duration:CFTimeInterval){
let animation = CABasicAnimation(keyPath: "transform.rotation");
animation.fromValue = 0;
animation.duration = duration;
animation.toValue = CGFloat(M_PI*2);
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear);
animation.repeatCount = Float.infinity;
layer.addAnimation(animation, forKey: "rotation");
}
usage (the duration is time it takes the layer to rotate 360 degress):
rotateLayer(subView.layer, duration: 2);

Animate UIImageView Diagonally

I'd like to be able to animate my UIImageView background in a diagonal fashion. Meaning the background would animate and scroll from the top left of the screen towards the bottom right of the screen. Ideally, this would be a continuous animation.
I have the directions figured out, however, what I have seems to take a copy of the background & animate it over a static background. This causes for a weird effect.
See gif:
Here is the code:
var imageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
self.setup();
}
func setup() {
self.imageView.frame = self.view.bounds
self.imageView.image = UIImage(named: "myimage.jpg")
self.view.addSubview(self.imageView)
self.scroll()
}
func scroll() {
var theImage = UIImage(named: "myimage.jpg")!
var pattern = UIColor(patternImage: theImage)
var layer = CALayer()
layer.backgroundColor = pattern.CGColor
layer.transform = CATransform3DMakeScale(1,-1,1)
layer.anchorPoint = CGPointMake(0, 1)
var viewSize = self.imageView.bounds.size
layer.frame = CGRectMake(0,0, theImage.size.width + viewSize.width, viewSize.height)
self.imageView.layer.addSublayer(layer)
var startPoint = CGPointZero
var endPoint = CGPointMake(theImage.size.width, theImage.size.height + 15)
var animation = CABasicAnimation(keyPath: "position")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.fromValue = NSValue(CGPoint:startPoint)
animation.toValue = NSValue(CGPoint:endPoint)
animation.repeatCount = Float.infinity
animation.duration = 1.0
layer.addAnimation(animation, forKey: "position")
}
Is anyone able to figure out how to make the whole background scroll? Do i just need a larger image, and scroll that? If that is the case, what does the contentMode of the imageView need to be set at?
Thanks
---- Update
I've reworked the code a bit, and have a working version of what I wanted. I'm curious for some feedback, as I'm still not 100% comfortable with animations in general (but i'm learning! :) )
-- I removed the whole background image in general, as DuncanC suggested it wasn't serving a good purpose. Now, i'm just making an image layer, trying to make if sufficiently big, and looping the animation. Thoughts?
override func viewDidLoad() {
super.viewDidLoad()
self.scroll()
}
func scroll() {
var theImage = UIImage(named: "myimage.jpg")!
var pattern = UIColor(patternImage: theImage)
var layer = CALayer()
layer.backgroundColor = pattern.CGColor
layer.transform = CATransform3DMakeScale(1,-1,1)
layer.anchorPoint = CGPointMake(0, 1)
// i'm making the view large here so the animation can keep running smoothly without
// showing what is behind our image
// is there a better way to do this?
var viewSize = CGSizeMake(self.view.bounds.size.height * 10, self.view.bounds.size.width * 10)
layer.frame = CGRectMake(0,0, theImage.size.width + viewSize.width, viewSize.height)
self.view.layer.addSublayer(layer)
var startPoint = CGPointMake(-theImage.size.width, -theImage.size.height)
var endPoint = CGPointMake(0, 0)
var animation = CABasicAnimation(keyPath: "position")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.fromValue = NSValue(CGPoint:startPoint)
animation.toValue = NSValue(CGPoint:endPoint)
animation.repeatCount = Float.infinity
animation.duration = 3.0
layer.addAnimation(animation, forKey: "position")
}
**Result:*
Your code doesn't make a lot of sense. You have an image view that contains the image myimage.jpg, and then you create a CALayer that contains that image as a pattern color. You add the layer to your image view and animate it's position.
Just use a UIView animation and animate the center of your image view directly. If you're using AutoLayout then you'll need to add horizontal and vertical position constraints, wire them up as IBOutlets, and then in your animation block change the constraints and call layoutIfNeeded() on the image view's superview.

UIView.animateWithDuration: animation always stops at original position

I added an ImageView in the middle of my view (no constraints set).
With this code I want to move this ImageView from its original position to a new one.
Unfortunately, it moves from the new to its original position - why?
let opts = UIViewAnimationOptions.CurveEaseInOut
UIView.animateWithDuration(1, delay: 0, options: opts, animations: {
self.ivSun.center.x += 100
}, completion: nil)
Add this after completion of your animation.
self.ivSun.layer.position = self.ivSun.layer.presentationLayer().position
I have code that implemented in my game.
CATransaction.begin()
CATransaction.setCompletionBlock { () -> Void in
self.viewBall.layer.position = self.viewBall.layer.presentationLayer().position
}
}
var animation = CABasicAnimation(keyPath: "position")
animation.duration = ballMoveTime
animation.fromValue = NSValue(CGPoint: viewBall.layer.presentationLayer().position)
animation.toValue = NSValue(CGPoint: CGPointMake(self.borderRight, self.borderMiddle))
animation.removedOnCompletion = false
animation.fillMode = kCAFillModeForwards
viewBall.layer.addAnimation(animation, forKey: "transform")
CATransaction.commit()
Change position value as you need.
Try this one.
func animateImage()
{
UIView.animateWithDuration(3.0, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in
self.imageView.center = CGPointMake(self.imageView.center.x+10, self.imageView.center.y+10)
}, completion: nil)
}
Without knowing more about the context and related code it's difficult to give an answer on "why" it's snapping back to its original position, but as an alternative you could set the completion handler with whatever you'd like as the final position/coordinate.
Generally I use constraints on my widgets/views, and I animate their values (versus animating the widgets' frame, for example) ... with excellent results.
This is due to autolayout. Constraints need to be changed and updated in the the animation as seen below:
- (IBAction)moveAction:(id)sender {
self.spaceConstraint.constant += 220;
[UIView animateWithDuration:0.5 animations:^{
[self.imageView layoutIfNeeded];
}];
}
var animation = CABasicAnimation(keyPath: "position")
animation.duration = ballMoveTime
animation.fromValue = NSValue(CGPoint: viewBall.layer.presentationLayer().position)
animation.toValue = NSValue(CGPoint: CGPointMake(self.borderRight, self.borderMiddle))
animation.removedOnCompletion = false
animation.fillMode = kCAFillModeForwards
viewBall.layer.addAnimation(animation, forKey: "transform")
CATransaction.commit()

Resources