Only set CGPoint of the frame - objective-c

I have a problem that hopefully has a simple solution. I am trying to create a bobbing effect using a button, a timer, frame, cgaffinetransformrotations, and delays. Everything would be great, except that when the button is rotated and I set the frame of the button to decrease or increase the y by 10 or so pixels, the rotation makes the frame of the button bigger than it normally is. The end result is a button that constantly grows until it swallows the screen.
I tried making the upward and downward movements cgaffinetranslations, but that uses the transform property (which is the same one that the rotations use). The result is a very jumpy and non-realistic bob.
What I am trying to accomplish is just to set the origin component of the frame without having to specify a width and height, because even specifying a hard-coded width and height still makes it shrink when it is rotating and grow when it is approaching equilibrium again.
Any ideas?
Thanks!
CODE:
- (void)movePlay{
[self performSelector:#selector(moveDown:) withObject:play];
[self performSelector:#selector(rotateRight:) withObject:play afterDelay:0];
[self performSelector:#selector(moveUp:) withObject:play afterDelay:0.5];
[self performSelector:#selector(rotateLeft:) withObject:play afterDelay:1];
}
- (void)moveUp:(UIButton*)log{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
log.transform = CGAffineTransformMakeTranslation(0, -20);
[UIView commitAnimations];
}
- (void)rotateRight:(UIButton*)log{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
log.transform = CGAffineTransformMakeRotation(0.0174532925*10);
[UIView commitAnimations];
}

This is just an idea.
Try combining all the separate transformations together. So instead of committing independently
log.transform = CGAffineTransfor...,
combine them first with
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);
CGAffineTransformRotate(CGAffineTransform t1, CGFloat angle);
etc.

Related

setting the x and y points of a label through an animation in xcode

I am fading in a label and I am attempting to have it come in from the side of the view. I am using this code to fade it in:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[label setAlpha:1.0];
[label setFrame:CGRectMake(10,20,100,200)];
In the story board I have the X axis as -52 and I am trying to have it change to 10 in the 1.0 second animation. The fading part is working fine but I can't figure out how to change the x or y axis through the animation. I have tried a lot of different things but nothing is working. Any help is much appreciated!
You have to use frame property to set the x and y. Do not change the width/height.
[label setFrame:CGRectMake(10,20,label.frame.size.width,label.frame.size.height)];
The code you have shown does not actually show committing the animations. You should use the more modern block based animations that prevents this from happening
[UIView animateWithDuration:1.0f
animations:^{
label.alpha = 1.f;
CGRect frame = label.frame;
frame.origin = CGPointMake(10.f, 20.f);
label.frame = frame;
}];

Animate Rotation/Scale/Translate of UIImage at the same time

I am new to objective-c and I want to add an image to the screen, tweening it like in AS3, moving it from one end to the other of the screen while rotating around its own center point.
I tried with
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
// TRANSFORM SCREENSHOT
screenShotView.transform = CGAffineTransformRotate(screenShotView.transform, -M_PI * 0.05);
screenShotView.transform = CGAffineTransformScale(screenShotView.transform, 0.6, 0.6);
screenShotView.transform = CGAffineTransformTranslate(screenShotView.transform,
self.webView.frame.origin.x,
self.webView.frame.origin.y - self.webView.frame.size.height * 0.3
);
but with this code the image rotates around the center of the TransformIdentity. So while rotating and moving the rotation gets out of controll and the image isn't exactly at the position I loved it to be.
What is the right way to rotate and translate at the same time, translating the rotation center with the image?
and at least after transformation I want to add a close button to the right upper corner of the image. for that I need the new coordinates of the corner, too.
thnx!
I now ended with the following code, but I still don't know if this is the state of the art solution.
CGAffineTransform translate = CGAffineTransformMakeTranslation(self.webView.frame.origin.x,self.webView.frame.origin.y - self.webView.frame.size.height * 0.25);
CGAffineTransform scale = CGAffineTransformMakeScale(0.6, 0.6);
CGAffineTransform transform = CGAffineTransformConcat(translate, scale);
transform = CGAffineTransformRotate(transform, degreesToRadians(-10));
[UIView beginAnimations:#"MoveAndRotateAnimation" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:2.0];
screenShotView.transform = transform;
[UIView commitAnimations];
IOS 7's preferred way to do this would be using a block object. It has several advantages compared to the 'older' way of animating. Especially that it can make use of multi-core and video co-processing. Also the 'built-in' call back part (the completion part) is very useful, as it keeps any necessary state information and links to objects as needed.
CGAffineTransform translate = CGAffineTransformMakeTranslation(self.webView.frame.origin.x,self.webView.frame.origin.y - self.webView.frame.size.height * 0.25);
CGAffineTransform scale = CGAffineTransformMakeScale(0.6, 0.6);
CGAffineTransform transform = CGAffineTransformConcat(translate, scale);
transform = CGAffineTransformRotate(transform, degreesToRadians(-10));
// animation using block code
[UIView animateWithDuration:2.0
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
screenShotView.transform = transform;
}completion:^(BOOL finished){
// do something if needed
}];

List examples of how to "briefly draw attention" to an object on screen in iOS?

In iOS, how can one briefly draw attention to an object on screen? Suppose, create a brief glow or cause a shadow to appear and then disappear?
For the purposes of this question, let's define "object on screen" as an instance of UIImageView.
Also, if possible provide an example of how to draw attention to a button.
Most people list code, but I'm sticking to describing some examples;
I've seen objects briefly grow and shrink back to their normal size to draw attention
Bejeweled (a Popcap game) lets diamonds briefly 'shine' (as if sunlight passed over it) to give you a subtle hint
I've seen certain applications use a hand or a fictive character point to a certain object briefly
And of course, you could always introduce a talking paperclip to tell you what's what.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1f];
yourView.transform = CGAffineTransformMakeScale(1.1, 1.1);
[UIView commitAnimations];
Or, of course the same thing with a block animations. And after the attention got away from your view you can use :
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1f];
yourView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
Here is a simple hop animation...
- (void)drawAttn
{
float jumpHeight = 20.0;
CGPoint originalPoint = objectForAttn.center;
CGPoint jumpPoint = CGPointMake(objectForAttn.center.x, objectForAttn.center.y - jumpHeight);
[UIView animateWithDuration:0.20 delay:0.0 options:UIViewAnimationOptionAutoreverse animations:^{
[objectForAttn setCenter:jumpPoint];
} completion:^(BOOL finished) {
/* do other stuff after hop */
}];
}
My app QCount (free in the store, tap a "wrong" number 3 times) uses a fade animation as follows:
(note I wrote this when I was REALLY new to iOS, so there is probably a more compact way to write it)
aLabel = // a UILabel I get from somewhere
aColor = aLabel.backgroundColor;
[UIView animateWithDuration:0.2
delay: 0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
aLabel.alpha = 0.0;
}
completion:^(BOOL finished){
// Wait .2 seconds and then fade in the view
[UIView animateWithDuration:.2
delay: 0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
aLabel.alpha = 1.0;
}
completion:nil];
}];
There are lots of options: hopping, underlining, vibrating, blinking, rotating, scaling, endarkening around, and their combinations.
But IMO, shine effect on "slide to unlock" text is excellent.
You can check it out here:
iPhone "slide to unlock" animation
I wanted to draw attention to a label whose value had changed. This simple animation produces a nice 'I've changed' animation...
//copy the label
UILabel *newPageLabel = [[UILabel alloc] initWithFrame:_countLabel.frame];
[newPageLabel setFrame:CGRectOffset(newPageLabel.frame, 0, 0)];
newPageLabel.text = _countLabel.text;
newPageLabel.textAlignment = _countLabel.textAlignment;
newPageLabel.backgroundColor = _countLabel.backgroundColor;
newPageLabel.textColor = _countLabel.textColor;
newPageLabel.font = _countLabel.font;
//scale and fade out the copied label
[self.navigationController.toolbar addSubview:newPageLabel];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionLayoutSubviews
animations:^{
newPageLabel.transform = CGAffineTransformMakeScale(2,2);
newPageLabel.alpha = 0;
}
completion:^(BOOL finished){
[newPageLabel removeFromSuperview];
}
];

How can I program a custom partial or sub view for a calculator?

I'm building a basic calculator app. The calculator is already fully functional with basic features. The problem I'm having is I ran out of room on the screen to add other, more advanced features. Ideally what I would like to do is create some kind of subclass and view that slides up to to the bottom of the label (where the completed calculations are displayed), when a button on the bottom of the screen is pressed. In other words, I want a view with more operators and computation options to slide up to the bottom of the label and I dont want this view to cover up any digits that are being displayed in the label. Is there anyway to achieve this?
Yes, you can. When your button is pressed, create your new view (with the extra functions), add it as a subview to self.view, and animate a change to it's frame, so that it's frame changes from below the visible view to just below your digits.
Like this:
-(void) buttonPressed {
UIView *myNewView = << create your view >>
myNewView.frame = CGRectMake(0,480, 320,200); // or whatever your width and height are
// 480 means it will be below the visible frame.
[self.view addSubview: myNewView];
float bottom_Y_of_digit_display = 100;// or wherever it is...
[UIView beginAnimations:nil contenxt:nil];
[UIView setAnimationDelay: 0.0];
[UIView setAnimationDuration: 1.0]; // one second.
myNewView.frame = CGRectMake(0,bottom_y_of_digit_display, 320,200);
[UIView commitAnimations];
}
You can use UIAnimations to create an animation out of any changes to UIView properties. You can make your UIView hidden by settings its frame.origin.y to 480 and then change the rect and wrap it in a UIAnimation.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
[UIView commitAnimations];
UPDATE
If you are targeting iOS 4.0 and later then you should use the new UIAnimations interface.
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:0.75 delay:0 options:options
animations:^(){
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
}
completion:^(BOOL finished){
//Do something upon completion
}];

Obj C: How to scale only to up?

Hey everbody. I have a little issue here. I just want to scale my view, but only to up. I mean, i dont want it move out from original coords, i just want to scale in one direction, without affecting the position.
[UIView beginAnimations: #"myViewAnimation" context: nil];
[UIView setAnimationDuration:1.0];
redView.transform = CGAffineTransformMakeScale(1.0, 3.0);
[UIView commitAnimations];
Thanks!
Origin of all UIView transforms is its layer's anchorPoint, which is in the center of the view by default. Set anchorPoint to CGPointZero so view will be scaled to the right and upwards and its current position will be fixed:
redView.layer.anchorPoint = CGPointZero;
...
UIView beginAnimations: #"myViewAnimation" context: nil];
[UIView setAnimationDuration:1.0];
redView.transform = CGAffineTransformMakeScale(1.0, 3.0);
[UIView commitAnimations];
Note also that view's frame is calculated using its layer's anchorPoint so you may need to also adjust your view's frame accordingly
To access view's layer you will need to add QuartzCore.framework to link with your project and import <QuartzCore/QuartzCore.h> header file.