How to animate zooming into an image without changing the image size - objective-c

How can I recreate a slight zoom in to an image using animations?
I have a uiimageview and I want it to look like we zoom in to the image after 1 second, lasting 1 second, but the uiimageview size must not change.
Something like this but the image view changes its size:
[UIView animateKeyframesWithDuration:1
delay:0
options:UIViewKeyframeAnimationOptionBeginFromCurrentState
animations:^{
[UIView addKeyframeWithRelativeStartTime:0
relativeDuration:1
animations:^{
self.imageView.transform =CGAffineTransformMakeScale(1.1, 1.1);
}];
}
completion:^(BOOL finished) {
}];

You can add UIImageView as a child view of UIScrollView and set its zooming options. Here, look at this article.

Related

UIView not animating constraint change

I have a question regarding the UIView method:
+ (void)animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
Basically I am just trying to set a height constraints constant to 0 and have the change look like its slowly shrinking...
My Code looks like this:
[UIView animateWithDuration:0.7
animations:^{
//hide the Title
self.titleCellHeigthConstraint.constant = kLabelHeightZero;
[self.contentView layoutIfNeeded];
}
completion:nil];
Unfortunately it's not animating. It simply makes all changes appear with a little delay (which might be the 0.7 seconds specified in the method).
Now my question is if there is any way to get the UIView to animate the change?
Thanks in Advance!
Edit:
The weird thing is if I reverse the changes in an animated fashion it does it exactly the way I want it. The code I'am using for that is:
//animate layout changes
[UIView animateWithDuration:0.7
animations:^{
//hide activity indicator and label
[self.activityIndicator stopAnimating];
[self.label setHidden:YES];
}
completion:^(BOOL arg0){
[UIView animateWithDuration:0.3
animations:^{
//show title label
self.titleCellHeigthConstraint.constant = kDefaultLabelHeight;
[self.contentView layoutIfNeeded];
}];
}];
You want to change the properties of the UIView not the NSLayoutConstraint in the animation method. I.e. Change the layout constraint's constant before the UIView method and then change the UIView's frame property in the animation method.
This way you won't need to call layoutIfNeeded.

Scaling UIView using transform after animating frame change causes UIView to jump back to original frame before scaling

I'm trying to scale a UIView (with animation) after I move it (with animation). The problem is, when the scaling animation begins, it jumps back to the original position. Why?
[UIView animateWithDuration:t delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
// Drop the ball
CGRect frame = coinView.frame;
frame.origin.y += d;
coinView.frame = frame;
coinView.shouldSparkle = NO;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 animations:^{
// Initial scale up for ball "poof"
coinView.transform = CGAffineTransformScale(coinView.transform, 1.5, 1.5);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 animations:^{
coinView.transform = CGAffineTransformScale(coinView.transform, 0.000001, 0.000001);
} completion:^(BOOL finished) {
[coinView removeFromSuperview];
}];
}];
}];
EDIT: This is how I generated my d:
static CGFloat groundPositionY = 325;
CGRect convertedFrame = [coinView.superview convertRect:coinView.frame toView:self.view];
CGFloat d = groundPositionY - CGRectGetMaxY(convertedFrame);
EDIT2: Okay, so I changed the second UIView animation to the following and I discovered that the jump (and the scale down) happens before the second animation occurs, i.e. when animateWithDuration:delay:options:animations:completion: is called.
[UIView animateWithDuration:5 delay:3 options:0 animations:^{
coinView.transform = CGAffineTransformScale(coinView.transform, 1.5, 1.5);
} completion:nil];
I tested your code and it works fine for me. How do you generate your d? and on which block exactly it goes back?
I found the problem...
The coinView is a subview of a child view controller's view. The problem comes from the fact that I overrode that child view controller's viewDidLayoutSubviews method to lay out all the coinView's, so whenever that method was called, the coin view would move back to its original position and size intended by the child view controller.
Thanks for all of your help, repoguy and sergio!!

Resize UITableView when I slide up a UIView, just like how it happens when the keyboard is shown

I am sliding up a UIView which has a UIDatePicker as a subview. This is added above my UITableView, but unfortunately some of the tableView rows are still under my UIView.
UITableView is pushed up with keyboard:
UITableView is NOT pushed up with my view, covers up last few fields:
Is it possible to resize the UITableView dynamically when I slide up my view, just like when the keyboard is shown when in a tableView and all the rows are still able to be seen?
EDIT:
Just found a great Apple example: http://developer.apple.com/library/ios/#samplecode/DateCell/Introduction/Intro.html
Yes, it is possible. You could just go ahead and change the size of the UITableView dynamically as part of the animation that slides up the view. If you want to do what the UITableView actually does in response to the keyboard, leave its size alone and instead change its content inset and scroll indicator insets. See my answer here and the examples linked to:
uitableview not resizing with keyboard
Ok, it was easier than I thought. In my case, when I touch a row, I want the picker to show and the tableView to change its height, so I use:
[UIView animateWithDuration:0.4 delay:0.0 options: UIViewAnimationCurveEaseOut animations:^{
self.pickerView.frame = CGRectMake(0, self.view.bounds.size.height-200, self.view.bounds.size.width, self.pickerView.frame.size.height);
// shrink the table vertical size to make room for the date picker
CGRect newFrame = self.tableView.frame;
newFrame.size.height -= self.pickerView.frame.size.height;
self.tableView.frame = newFrame;
} completion:nil];
Then when I click the done button, and want to return the tableView back to the full height and hide my datePicker, I use:
- (void)doneWithPicker:(BOOL)remove {
CGRect newFrame = self.tableView.frame;
newFrame.size.height += self.pickerView.frame.size.height;
self.tableView.frame = newFrame;
[UIView animateWithDuration:0.4 delay:0.0 options: UIViewAnimationCurveEaseOut animations:^{
self.pickerView.frame = CGRectMake(0, self.view.bounds.size.height+300, self.view.bounds.size.width, self.pickerView.frame.size.height);
} completion:^(BOOL finished){
if (remove) {
[self.pickerView removeFromSuperview];
self.pickerView = nil;
}
}];
}
Also, when adding the pickerView as a subview, make sure to add it to the window:
[self.view.window addSubview:self.pickerView];

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
}];