How to animate expand and shrink uiview in place? - iphone

I have a series of uiviews, and i want to create an animation where a button press event will expand the uiview from the bottom and reveal more information about the view. Another button press will shrink the view back to original.
How do i proceed with this?
There are a series of uiviews laid out in a horizontal scroll view like a coverflow. I want to display additional information about each uiview on click of a button.
Do drop a comment if you need more information.
TIA,
Praveen S

This code will expand your view...do the reverse to shrink it
CGRect tempFrame=view.frame;
tempFrame.size.width=200;//change acco. how much you want to expand
tempFrame.size.height=200;
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.2];
view.frame=tempFrame;
[UIView commitAnimations];

For that use this code
In .h file
#import <UIKit/UIKit.h>
#interface ExpandedViewController : UIViewController
{
UIView * expandiView;
BOOL viewExpanded;
}
- (IBAction)expandOrShrinkView:(id)sender;
#end
and in your .m file
- (void)viewDidLoad
{
[super viewDidLoad];
aview = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
aview.backgroundColor = [UIColor redColor];
[self.view addSubview:aview];
viewExpanded = NO;
}
And in your button action add this code
- (IBAction)expandOrShrinkView:(id)sender {
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
if (!viewExpanded) {
viewExpanded = YES;
aview.frame = CGRectMake(10, 10, 100, 200);
}else{
viewExpanded = NO;
aview.frame = CGRectMake(10, 10, 100, 100);
}
} completion:nil];
}
When you click the button first time it will expand the view from bottom and when you click the button second time it will shrink the View from bottom change the frame size to your need..
And if you want shrink function in another button than use two action method like this
- (IBAction)expandView:(id)sender {
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
aview.frame = CGRectMake(10, 10, 100, 200);
} completion:nil];
}
- (IBAction)ShrinkView:(id)sender {
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
aview.frame = CGRectMake(10, 10, 100, 100);
} completion:nil];
}

Related

Subviews are not removing while removing the superview in iPad

I created a UIView.A search bar is added as subview on the view.The search bar is also created through code.
I have given a UIAnimation to the view to get a dropdown like effect to the view.
Upto this point it is working fine.
The problem is when i remove the superview the view is go but the search bar is still there.
Here are some codes:
#interface ATViewController : UIViewController<UISearchBarDelegate>
{
UIView *dropView;
UISearchBar *searchBar;
}
- (void)viewDidLoad
{
dropView = [[UIView alloc]initWithFrame:CGRectMake(70, 70, 150, 100)];
searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,0,150,0)];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(IBAction)buttonClicked:(id)sender{
// self.searchBar.delegate = self;
[dropView addSubview:searchBar];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.9];
dropView.backgroundColor = [UIColor blueColor];
dropView.frame = CGRectMake(70, 70, 150, 550);
self.searchBar.frame=CGRectMake(0,0, 150, 40);
[UIView commitAnimations];
[self.view addSubview:dropView];
}
-(void)doSingleTap:(UITapGestureRecognizer *)sender
{
switch (sender.numberOfTapsRequired) {
case 1:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
dropView.frame = CGRectMake(70, 70, 150, 0);
self.searchBar.frame=CGRectMake(0, 0, 150, 0);
[UIView commitAnimations];
break;
default:
break;
}
}
Adding the subview
After removing the subView
You are not removing the super view in code. You are just reducing its height to zero. If you want the searchBar to be clipped along with the dropView then set dropView's clipToBounds to YES.
i.e;
dropView.clipToBounds = YES:
before you reduce its height to zero.
Noticed that you are reducing the search bars height to zero as well. But I think you are not allowed to edit the height of the UISearchBar.

Hide all View containing By making height 0 of parent UiView

I am making one animation and in it i Have to make height 0 of one UIView named "subView".
now that subView contain one UIButton and UIImageView.
now i make height 0 by this method on button click
#interface ViewController : UIViewController
{
IBOutlet UIView *suvView;
IBOutlet UIButton *subButton;
IBOutlet UIImageView *imgview;
}
-(IBAction)hide:(id)sender;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.view addSubview:suvView];
[suvView addSubview:subButton];
[suvView addSubview:imgview];
}
-(IBAction)hide:(id)sender
{
[UIView beginAnimations:nil context:suvView];
[UIView setAnimationDuration:0.25];
[suvView setFrame:CGRectMake(0, 94, 320, 0)];
[UIView commitAnimations];
}
#end
but when i make height 0 than View named "subButton" and "imgview" are look as it is.
i want to make Them hidden when subView height is 0.
i am using XCode 4.5
If you want to hide them without resizing: [mainview setClipsToBounds:YES]
You have two methods for doing this :-
Firstly, If you are making the suvViews height 0 then you do not need to remove it. But simply hide the imgview and the subButton like
-(IBAction)hide:(id)sender
{
[UIView beginAnimations:nil context:suvView];
[UIView setAnimationDuration:0.25];
[suvView setFrame:CGRectMake(0, 94, 320, 0)];
[UIView commitAnimations];
subButton.hidden = YES;
imgview.hidden = YES;
}
#end
Also what you can do is reduce the heights of subButton and imgview with the suvView's height like
-(IBAction)hide:(id)sender
{
[UIView beginAnimations:nil context:suvView];
[UIView setAnimationDuration:0.25];
[suvView setFrame:CGRectMake(0, 94, 320, 0)];
[imgview setFrame:CGRectMake(0, x, y, z];
[subButton setFrame:CGRectMake(0, x, y, z];
[UIView commitAnimations];
}
where x,y,z are the coordinates of the imgview and the subButton. Hope this helps.
//try this code for view animation
-(IBAction)hide:(id)sender
{
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationCurveEaseOut
animations:^{
[suvView setFrame:CGRectMake(0, 94, 320, 0)];
}
completion:nil];
}
Add the following line before starting the animation:
subButton.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
imgView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
Or you could do this from the interface builder also by setting the vertical and horizontal resize for each sub view (the button and image view)
Btw you should be using the apple recommended block based animation(if you are using iOS 4.0 and above) rather than beginAnimations: and commitAnimations:.

UIAnimation - Show UIView from button.frame.origin.y

I have a UIButton somewhere on my view. On touch event of button I making a UIView appear. The UIAnimation I have used make the view appear from top of window. But I want it to appear from button.frame.origin.y . Before touching the button the view is not visible. On touching the button view should start appearing from above position.
Here is the code :
-(IBAction) ShowInfowView:(id)sender{
CGRect rect = viewInfo.frame;
rect.origin.y = rect.size.height - rect.size.height+58.0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.70];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewInfo.frame = rect;
[UIView commitAnimations];
}
This is how I am hiding the view again :
-(IBAction) HideInfoView:(id)sender{
CGRect rect = viewInfo.frame;
rect.origin.y = -rect.size.height;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.70];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewInfo.frame = rect;
[UIView commitAnimations];
}
In viewDidLoad I am doing the following :
CGRect rect = viewInfo.frame;
rect.origin.y = -rect.size.height;
viewInfo.frame = rect;
UPDATE:
Please see this example. Here view is appearing from top of screen. I want it to appear from button y axis. For that matter please consider button y position a bit upwards.
So you want a slide-in effect, but not from the top of the screen, just some arbitrary value?
One way to do it:
1) You should create a view that has the dimensions and position of your desired view AFTER animation finishes, we'll call it baseview.
2) Set this baseview property clipsToBounds to YES. This will make all subviews that are outside of the baseview's frame invisible.
3) Add your animating view as a subview of the baseview, but set the frame so it is invisible (by plcacing it above the baseview):
frame = CGRectMake(0, -AnimViewHeight, AnimViewWidth, AnimViewHeight);
4) Animate the animview frame:
//put this inside of an animation block
AnimView.frame = CGRectMake(0, 0, AnimViewWidth, AnimViewHeight);
EDIT:
Example:
//define the tags so we can easily access the views later
#define BASEVIEW_TAG 100
#define INFOVIEW_TAG 101
- (void) showInfo
{
//replace the following lines with preparing your real info view
UIView * infoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[infoView setBackgroundColor: [UIColor yellowColor]];
[infoView setTag: INFOVIEW_TAG];
//this is the frame of the info view AFTER the animation finishes (again, replace with real values)
CGRect targetframe = CGRectMake(100, 100, 100, 100);
//create an invisible baseview
UIView * baseview = [[UIView alloc] initWithFrame:targetframe];
[baseview setBackgroundColor: [UIColor clearColor]];
[baseview setClipsToBounds: YES]; //so it cuts everything outside of its bounds
[baseview setTag: BASEVIEW_TAG];
//add the nfoview to the baseview, and set it above the bounds frame
[baseview addSubview: infoView];
[infoView setFrame:CGRectMake(0, -infoView.bounds.size.height,
infoView.bounds.size.width, infoView.bounds.size.height)];
//add the baseview to the main view
[self.view addSubview: baseview];
//slide the view in
[UIView animateWithDuration: 1.0 animations:^{
[infoView setFrame: baseview.bounds];
}];
//if not using ARC, release the views
[infoview release];
[baseview release];
}
- (void) hideinfo
{
//get the views
UIView * baseView = [self.view viewWithTag: BASEVIEW_TAG];
UIView * infoView = [baseView viewWithTag: INFOVIEW_TAG];
//target frame for infoview - slide up
CGRect out_frame = CGRectMake(0, -infoView.bounds.size.height,
infoView.bounds.size.width, infoView.bounds.size.height);
//animate slide out
[UIView animateWithDuration:1.0
animations:^{
[infoView setFrame: out_frame];
} completion:^(BOOL finished) {
[baseView removeFromSuperview];
}];
}
I have done exactly what you're trying in my recent project.
The following steps should make this work:
1. In your viewDidLoad: you init your viewToFadeIn like this:
viewToFadeIn = [[UIView alloc] initWithFrame:CGRectMake(20,self.view.frame.size.height+10, self.view.frame.size.widh-40, 200)];
//its important to initalize it outside your view
//your customization of this view
[self.view addSubview:viewToFadeIn];
2.your ShowInfowView: Method should look like this:
` -(IBAction) ShowInfowView:(id)sender{
[UIView beginAnimations:#"fadeIn" context:NULL];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
viewToFadeIn.transform = CGAffineTransformMakeTranslation(0, -290);
//290 is in my case, try a little for your correct value
[UIView commitAnimations];
}
3.yourHideInfoView:` Method looks like this
-(IBAction) HideInfoView:(id)sender{
[UIView beginAnimations:#"fadeOut" context:NULL];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
viewToFadeIn.transform = CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations];
}
EDIT:
4. animationFinishedMethod:
- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
if ([animationID isEqual:#"fadeIn"]) {
//Do stuff
}
if ([animationID isEqual:#"fadeOut"]) {
//Do stuff
}
}
SEE THIS
This should do the trick. Good luck
Your problem is not clear (for me).
What is this?
rect.origin.y = rect.size.height - rect.size.height+58.0;
Is 58 origin of your UIButton?
You should use sender.frame etc
Use blocks to animate like this
[UIView animateWithDuration:0.5f animations:^{
// Animation here
} completion:^(BOOL finished) {
// onComplete
}];
- (void) slideIn{
//This assumes the view and the button are in the same superview, if they're not, you'll need to convert the rects
//I'm calling the animated view: view, and the button: button...easy enough
view.clipToBounds = YES;
CGRect buttonRect = button.frame;
CGRect viewRect = CGRectMake(buttonRect.origin.x, buttonRect.origin.y + buttonRect.size.height, view.bounds.size.width, 0);
CGFloat intendedViewHeight = view.height;
view.frame = viewRect;
viewRect.size.height = intendedViewHeight;
[UIView animateWithDuration:.75 delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
view.frame = viewRect;
}completion:nil];
}
This will cause the the view to appear to slide out from under the button. To slide the view back in, you just reverse the animations. If you wish to slide it up from the button, you'll need to make sure your starting 'y' is the 'y' value of the button (rather than the 'y' + 'height') and animate both the height and y values of the view that needs animating.

searchDisplayControllerWillEndSearch not resizing searchbar

Just wondering why and need to solve it. i have this searchbar looks like this.
which clicked will move up to the top and expend to 0,0,320,searchbar's height.
which clicked Cancel, it should resize back to 33,55,270, searchbar's height. but it doesn't
the searchDisplayControllerDidEndSearch will work to resize back, however there is a 1 sec lag that user could see the changes. any body why in searchDisplayControllerWillEndSearch the animation resize wound't work ?.
thanks for the comments and feedback.
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[UIView animateWithDuration:.1
animations:^{
controller.searchResultsTableView.frame = frogTableView.frame;
searchDisplayController.searchResultsTableView.frame = frogTableView.frame;
searchDisplayController.searchBar.frame = CGRectMake(32,
55,
270,
searchDisplayController.searchBar.frame.size.height);
searchBar.frame = CGRectMake(32,
55,
270,
searchBar.frame.size.height);
frogTableView.frame = CGRectMake(frogTableView.frame.origin.x,
121,
frogTableView.frame.size.width,
frogTableView.frame.size.height);
notePad.frame = CGRectMake(notePad.frame.origin.x,
45,
notePad.frame.size.width,
notePad.frame.size.height);
searchDisplayController.searchResultsTableView.frame = frogTableView.frame;
}
completion:^(BOOL finished){
//whatever else you may need to do
}];
}
I had the same trouble after I started to use UISearchBar with UISearchDisplayController. The solution I came up with is to place a search bar on a view:
UIView * searchBarSubview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, MENU_WORK_AREA_WIDTH, SEARCH_BAR_HEIGHT)] ;
searchBarSubview.autoresizesSubviews = YES;
searchBarSubview.backgroundColor = [UIColor clearColor];
UISearchBar * globalSearchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, MENU_WORK_AREA_WIDTH, SEARCH_BAR_HEIGHT)] autorelease];
globalSearchBar.tintColor = [UIColor blackColor];
globalSearchBar.delegate = self;
[globalSearchBar setBackgroundImage:[UIImage alloc]];
and resize the view instead of search bar in searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
// Slide in to the final destination
searchBarSubview.frame = CGRectMake(0, 0, MENU_WORK_AREA_WIDTH, SEARCH_BAR_HEIGHT);
[UIView commitAnimations];

How to specify a size to a UIAlert

I am trying to display a UIImage in a UIAlert.
I want to display it nearly fullscreen. For example my image has a 300x450px size.
Well I add it as a subview to my UIAlert.
But the UIAlert has default coordinates to keep it centered.
So I can add a image bigger than the UIAlert frame, but it covers the UIAlert...
I tried to specify a frame for my UIAlert, but it has no effect on it.
In fact I would like to add my image as a real content of the UIAlert, as well as simple text.
Is this possible ?
Consider writing your own Dialog popup instead of messing with the UIAlertView. If you want the 'bounce-in' animation that can easily be achieved using transform animations. Here is a simple popup dialog box I've just made.
To test it out create a new View-Based Application project and add this class. Then you can test it by adding the 'usage' code below to your *ViewController.m
This is a very simple example to demo the theory. It would make more sense to have a static method in SimpleDialog that shows the popup, but I didn't want to make the example overly complex.
SimpleDialog.h
#import <UIKit/UIKit.h>
#interface SimpleDialog : UIView
{
}
- (void) show;
#end
SimpleDialog.m
#import "SimpleDialog.h"
#define BOUNCE_SPEED 1
#implementation SimpleDialog
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
self.backgroundColor = [UIColor greenColor];
UIButton* closeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
closeButton.frame = CGRectMake(0, 0, 200, 20);
closeButton.center = self.center;
[closeButton setTitle:#"Close" forState:UIControlStateNormal];
[closeButton addTarget:self action:#selector(hide) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:closeButton];
}
return self;
}
- (void) show
{
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window)
{
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
[window addSubview:self];
self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2*BOUNCE_SPEED];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(bounceInStopped)];
self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
[UIView commitAnimations];
}
- (void)bounceInStopped
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.15*BOUNCE_SPEED];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(bounceOutStopped)];
self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
[UIView commitAnimations];
}
- (void)bounceOutStopped
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.15*BOUNCE_SPEED];
self.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
}
- (void) hide
{
[self removeFromSuperview];
}
#end
Usage
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton* popButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
popButton.frame = CGRectMake(0, 0, 200, 20);
popButton.center = self.view.center;
[popButton setTitle:#"Pop" forState:UIControlStateNormal];
[popButton addTarget:self action:#selector(showIt) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:popButton];
}
- (void) showIt
{
SimpleDialog* simple = [[SimpleDialog alloc] initWithFrame:CGRectMake(0, 0, 300, 400)];
simple.center = self.view.center;
[self.view addSubview:simple];
[simple show];
[simple release];
}
Yes this is possible.
But it requires to customize the UIAlertView.
Using UIAlertView customization you can add anything.