resizing a UIControl in an animated fashion - ios

I have created a button which I want to expand/contract. I found a way to get the x,y coordinates along with width and height. Using these I call CGRectMake function to redraw the button. I am trying to figure out how to redraw in an animated fashion. Below is my attempt but I am almost sure that there are better ways of doing this. Any comments?
pointX = navigateBtn.frame.origin.x;
pointY = navigateBtn.frame.origin.y;
height = CGRectGetHeight(navigateBtn.frame);
width = CGRectGetWidth(navigateBtn.frame);
for (int i=1;i<=800000;i++) {
int k=i/100000;
navigateBtn.frame=CGRectMake(pointX, pointY, width, height*k);
}
Thanks in advance.

All you need to know is what the destination rect will be and then you can animate like this
[UIView animateWithDuration:0.25f
animations:^{
navigateBtn.frame = endFrame;
}];

No. Don't try to animate things yourself.
Use UIView animation. A good tutorial is available from Ray Wenderlich: http://www.raywenderlich.com/2454/how-to-use-uiview-animation-tutorial
But to be perfectly honest you should probably start with an introductory iOS programming book. The way you phrased your question makes me think that you still have a lot of fundamentals to learn.

Related

Resize subviews on animated frame change (autoresizing mask)?

I know that it works if I change the view's frame via the changing of a layer's transform (in this case it simply takes a view with all the subviews and works with it as if it is a single image). It is not good enough for me to use it because:
It is too hard to calculate the appropriate position;
I use HMLauncherView which has some logic based on frames not
transforms.
I tried a lot of ways described here but it seems they are all for autolayout because none of them works. Depending on the type of the autoresizing mask some elements jump to their destination position and some of them are not affected at all or affected via strange ways.
How to solve such issue? Are there ways to solve this via an autoresizing mask?
EDITED
Animation code (the same result is for setting of center/bounds):
[UIView animateWithDuration:0.3 animations:^{
lastLauncherIcon.layer.transform = CATransform3DIdentity;
CGRect r = self.bounds;
r.origin.y = MAX(0, MIN(self.scrollView.contentOffset.y, self.scrollView.contentSize.height - self.bounds.size.height));
launcherIcon.frame = r;
} completion:^(BOOL finished) {
...
}];
The code of layoutSubviews seems to be extra because I have already tried to subclass UILabel which always jumps to the animation destination position. The investigation showed that the frame of this label is set when I set the view's frame/bounds only. In other cases label's setCenter, setFrame and setBounds are called when you call them directly.
This question is very similar but the suggested solution doesn't work for my case. I also found out I had broken something so the view with transformation doesn't appear on iOS 7.1 (maybe 7.x) but works on 8.3.

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.

uilabel disappears when being applied rotation on it

what I am having is
UIView
1.Image1
2.Image2
3.UILabel
like an image below
Then I apply rotation on UILabel by doing
- (void)viewDidLoad
{
testLabel.transform = CGAffineTransformMakeRotation(M_PI*0.25);
[super viewDidLoad];
}
and when I am running the application, the uilabe is disppearing after all. Look at the second image for your reference
Please point out what I am doing wrong here....and how to get the work done
Thanks
Watch out because Autolayout cause a lot of problems.
Try to deselect 'Use Autolayout'
It solves to me all the problems trying to translate objects.
Try multiplying by a smaller value against PI to see if it is rotating or just disappearing. If I remember correctly, rotations are not based on the center, but on the top-left corner, so you have to translate afterwards!
For instance, to rotate a video clip this is what I had to do:
CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI);
CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation(640, 480);
CGAffineTransform mixedTransform = CGAffineTransformConcat(rotation, translateToCenter);
[firstTrackInstruction setTransform:mixedTransform atTime:kCMTimeZero];
I rotated by PI first (180 degrees), but because the center of rotation is the top left corner, my video clip was now in the opposite quadrant, and needed to be transformed back! This may be what is happening with your label.
So try this, assuming your label is 42x21 dimensions..
CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI);
CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation(42, 21);
CGAffineTransform mixedTransform = CGAffineTransformConcat(rotation, translateToCenter);
label.transform = mixedTransform;
try putting the [super viewDidLoad] first :
- (void)viewDidLoad
{
[super viewDidLoad];
testLabel.transform = CGAffineTransformMakeRotation(M_PI*0.25);
}
AutoLayout and AutoResizing often cause difficulties when you apply transforms as these seem to alter the frame rather than the bounds and center of a view. Hence the automatic adjustments wreck havoc on your layout. Try to wrap the transformed label in a view that does not change dimensions and layout that view within its superview however you want.

Image magnification techniques, clarification needed

Before i start reinventing the wheel, i thought i'd check here to see if there are known image magnification techniques people know and love?
I am thinking .. for each image, on finger tap, i'd pop up an enlarged version of the same image (part of probably). Can i get away with a single image (and actually magnify it) or should i just swap images as user moves his/her finger?
Does this sound reasonable or, is this too much of a brute force approach?
From what I understand of your question - you want to tap on a thumbnail and it transitions to the full size/ larger size.
Best way of the top of my head would be to have a UIImageview with it's content mode set to UIViewContentModeAspectFill.
add the image view with CGSize of say 50X50 -- then add a UITapGestureRecogniser on it that triggers a function that does something like this:
- (void)tapped:(id)sender{
UIImageView *v = [(UITapGestureRecognizer *)sender view];
CGRect f = [v frame];
f.size = CGSizeMake(200,200);//or whatever size
[UIView animateWithDuration:0.25f
animations:^(){
[v setFrame:f];
}];
}
hope this helps
Cheers,
Michael

Rotate UIView based on UITouch

I'm working on a drawing app.
I want the user to be able to "drop" a shape on the screen and then move, resize or rotate it as desired.
The problem is with the rotation. I have the moving and resizing working fine.
I did this before with a rather complex and memory/processor-intensive process, which I am now trying to improve.
I've searched and searched but haven't found an answer similar to what I'm trying to do.
Basically, let's say the user drops a square on the "surface". Then, they tap it and get some handles. They can touch anywhere and pan to move the square around (working already), touch and drag on a resize handle to resize the square (working already), or grab the rotation handle to have the square rotate around its center.
I've looked into drawing the square using UIBezierPath or just having it be a subclass of UIView that I fill.
In either case, I'm trying to rotate the UIView itself, not some contents inside. Every time I try to rotate the view, either nothing happens, the view vacates the screen or it rotates just a little bit and stops.
Here's some of the code I've tried (this doesn't work, and I've tried a lot of different approaches to this):
- (void) rotateByAngle:(CGFloat)angle
{
CGPoint cntr = [self center];
CGAffineTransform move = CGAffineTransformMakeTranslation(-1 * cntr.x, -1 * cntr.y);
[[self path] applyTransform:move];
CGAffineTransform rotate = CGAffineTransformMakeRotation(angle * M_PI / 180.0);
[[self path] applyTransform:rotate];
[self setNeedsDisplay];
CGAffineTransform moveback = CGAffineTransformMakeTranslation(cntr.x, cntr.y);
[[self path] applyTransform:moveback];
}
In case it isn't obvious, the thinking here it to move the view to the origin (0,0), rotate around that point and then move it back.
In case you're wondering, "angle" is calculated correctly. I've also wrapped the code above in a [UIView beginAnimations:nil context:NULL]/[UIView commitAnimations] block.
Is it possible to rotate a UIView a "custom" amount? I've seen/done it before where I animate a control to spin, but in those examples, the control always ended up "square" (i.e., it rotated 1 or more full circles and came back to its starting orientation).
Is it possible to perform this rotation "real-time" in response to UITouches? Do I need to draw the square as an item in the layer of the UIView and rotate the layer instead?
Just so you know, what I had working before was a shape drawn by a set of lines or UIBezierPaths. I would apply a CGAffineTransform to the data and then call the drawRect: method, which would re-draw the object inside of a custom UIView. This UIView would host quite a number of these items, all of which would need to be re-drawn anytime one of them needed it.
So, I'm trying to make the app more performant by creating a bunch of UIView subclasses, which will only get a command to re-draw when the user does something with them. Apple's Keynote for the iPad seems to accomplish this using UIGestureRecognizers, since you have to use two fingers to rotate an added shape. Is this the way to go?
Thoughts?
Thanks!
-(void)rotate{
CGAffineTransform transform;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationOptionBeginFromCurrentState];
myView.alpha = 1;
transform = CGAffineTransformRotate(myView.transform,0.5*M_PI);
[myView setUserInteractionEnabled:YES];
myView.transform = transform;
[UIView commitAnimations];
}
This might help.
for just simple rotation you might leave out the Animation:
-(void)rotate:(CGFloat)angle
{
CGAffineTransform transform = CGAffineTransformRotate( myView.transform, angle * M_PI / 180.0 );
myView.transform = transform;
}
I use a simple NSTimer to control a animation.

Resources