UIView deforms when it is animated to another position - ios

Im having a really stupid problem with a UIView. I create the UIView programatically and then make it a circle by making the corner radius half the height of the view looks like this:
But when I try to animate the circle to a different location it becomes all deformed like this:
Here is the code I am using to animate the view just a simple UIView.animateWithDuration:
UIView.animateWithDuration(2, delay: 0, options: UIViewAnimationOptions.AllowUserInteraction, animations: {
self.secondDot.frame.origin = CGPoint(x: self.view.frame.size.width - self.secondDot.frame.size.width, y: 0)
self.secondDot.frame.size = self.secondDot.frame.size
}, completion: nil)
I should also add that the circle doesn't always become deformed but more often than not it does. Please help any suggestions would be much appreciated.
EDIT: I should mention that the circle is in motion already before the
UIView.animationWithDuration occurs I don't know if that could be a
problem

What is the point of this line?
self.secondDot.frame.size = self.secondDot.frame.size
You either
want to resize the circle uniformly while moving
or not.
If case 1) the the newSize.width != newSize.height...but thats a problem because your circle is not a "square" anymore behind the scenes.
If case 2) just remove the lines.

I had exactely the same situation.
After some research, I've found comment in header file for setFrame method
// animatable. do not use frame if view is transformed since it will
not correctly reflect the actual location of the view. use bounds +
center instead.
I have decided to use setCenter instead of setFrame which solved the distortion issue.

Related

How to pinch to zoom a view without making the view bigger?

This is what I currently have:
func handlePinching(recognizer : UIPinchGestureRecognizer) {
self.layer.transform = CATransform3DMakeAffineTransform(CGAffineTransformScale(self.transform, recognizer.scale, recognizer.scale));
recognizer.scale = 1.0;
}
Using self.view.transform for that also makes it bigger. I want to make it zoom "internally" (I really don't know how to explain it).
So I'm not 100% sure to understand the question but I guess I get it.
For example you want to zoom on an image without zooming the other element of the UI (NavBar, Buttons, ...) right?
So I guess in you're example you're in a viewController, which means, when you change the scale of self.view you'll zoom everything. You have to apply the scale on the specific view that you want to zoom in.
In the example below, to zoom on the image, the image is inside of an UIImageView, and this imageView is subView of self.view. And you will just apply a transform on this imageView.
Moreover I think you get a little bit confused on how to zoom, considering the view you want to zoom is imageView you just need to do
imageView.transform = CGAffineTransformMakeScale(recognizer.scale,recognizer.scale)
I hope this answer your question, let me know if something is not clear.

Trouble with anchor point in CGAffineTransformScale

I'm trying to get a UIButton to scale but remain at its original center point, and I'm getting perplexing results with CGAffineTransformScale.
Here's the function in my UIButton subclass:
-(void)shrink {
self.transform = CGAffineTransformMakeScale(0.9,0.9);
}
With this code, the button scales to the top-left corner, but when I add code to try to set the anchor point (either of the following lines), the button gets relocated off screen somewhere:
[self.layer setAnchorPoint:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)];
//same result if I use bounds instead of frame
[self.layer setAnchorPoint:self.center];
Interestingly, this line causes the view to move down and to the right some distance:
[self.layer setAnchorPoint:CGPointMake(0, 0)];
Sorry, I know there are many posts on this topic already but I honestly read and tried at least a dozen and still couldn't get this to work. I'm probably just missing something incredibly simple.
The default anchor point is 0.5, 0.5. That is why setting it to 0, 0 moves the view down and to the right. Also, if you don't want the center to move, you need to re-adjust the center after scaling it.
Just readjust its position after shrinking it.
-(void)shrink {
CGPoint centerPoint = self.center;
self.transform = CGAffineTransformMakeScale(0.9,0.9);
self.center = centerPoint;
}

How to rotate the UIStepper vertically after setting up its scale?

I have set the scale of my stepper as follows :
m_stepper1.transform = CGAffineTransformMakeScale(0.6, 0.6);
After that if I try to rotate vertically, it doesn't make any effect on the stepper. It doesn't get rotated. I used the following code for rotation:
m_stepper1.transform = CGAffineTransformMakeRotation(M_PI / 2.0);
Please some one help me out with this.
You don't need an extra view to accomplish this, all you need is a concat transform. The way you're doing this resets the previous transform before adding the new one. This will add both.
[stepper setTransform:CGAffineTransformConcat(CGAffineTransformMakeRotation(M_PI_2), CGAffineTransformMakeScale(0.6, 0.6))];
If however, you'd like to make the transforms one at a time, you should use one of the transforms that takes an input transform as a parameter. This will also produce the result you're looking for.
[stepper setTransform:CGAffineTransformMakeRotation(M_PI_2)];
[stepper setTransform:CGAffineTransformScale(stepper.transform, 0.6, 0.6)];
You put the UIStepper on a UIView, and rotate UIView.
【edit】
The answer is my fault. Im sorry.
And correct answer is below.
The methods CGAffineTransformMake~ and CGAffineTransform~ have differences.
CGAffineTransformMake~ use for transform FIRST TIME.
If you want to overlap transform, you should use CGAffineTransform~.
This is an example.
CGAffineTransform scale = CGAffineTransformMakeScale(0.6f, 0.6f);
stepper.transform = CGAffineTransformRotate(scale, M_PI / 2.0f);
Please try this.

Having a portrait label in a landscape view

I've created a .xib with a landscape orientation UIView.
The problem I'm trying to solve is that I want a UILabel running vertically along the side with text reading from bottom of the view to the top, but I can't figure out how to do that. Is that possible?
Image to show what I mean
You need to rotate and then translate it to put it where you want it. Rotation happens around the center of the label which is why you then need to translate it.
If you laid out the text label with the upper left corner where you wanted it to end up (i.e. the displayed label looks like it rotates around the upper left corner point of the label), you'd use code something like:
- (void)viewDidLayoutSubviews {
CGAffineTransform transform = CGAffineTransformMakeRotation(3 * M_PI_2);
CGAffineTransform transform2 = CGAffineTransformConcat(transform, CGAffineTransformMakeTranslation(floor(-self.label.bounds.size.width / 2), floor(-self.label.bounds.size.width / 2)));
self.label.transform = transform2;
}
You might need to adjust the translation values slightly to get what you want, but you definitely want them to be integers (which I've done with floor) so the label is crisp.
Of course you can. You need to do a transform.
yourlabel.transform = CGAffineTransformMakeRotation(-M_PI/2);

Circular animation to make UIImageView appear

I have a "circular" image, something like a pie chart. I would like a nice appearing animation, like when a pie chart fills itself from 0 to the value.
I usually use something like this when I want to animate views :
[UIView animateWithDuration: 3.0
delay: 0.0
options: UIViewAnimationCurveEaseInOut
animations: ^ {
// The animation
}
completion: ^(BOOL finished) {
// On completion
} ];
Is it possible to do the same thing for a circular animation ? I really have no idea on how to do that.
Thanks for any leads !
Note : iOS 5, storyboards, ARC, and all that stuff :)
Edit : for future discussion, the image looks like this :
Okay, here it goes :)
First option (Easy one). You could use UIImageView's animationImages property. Make NSArray with animation images (in your case, circular images those fill from 0 to full circle), set animationDuration, and call [imageView startAnimating] (I'm assuming that your UIImageView is imageView), and you can call [imageView stopAnimating] when process is done.
Second:
Check out this link http://www.cocoacontrols.com/platforms/ios/controls/jpradialactivityindicator, I think that sample project does the almost same, as you are trying to do :)
Good Luck ;)
1) You can use CAShapeLayer
You can achieve it by animating the strokeStart and strokeEnd properties. You could create the path for the full circle and use the strokeStart and strokeEnd properties to only stroke a certain part of the circle.
2) Also, you can refer to this tutorial : Animating Pie Slices Using a Custom CALayer
Good Luck!!!

Resources