Dismiss a UIViewController from bottom to top instead of right to left - iphone

I am trying to dismiss a view controller from bottom to top instead of the standard right to left transition. Is this at all possible? Here is the code I have so far:
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect endFrame = self.view.frame;
endFrame.origin.y = screenRect.origin.y - screenRect.size.height;
UIView *aView = [[self.view retain] autorelease];
[self.view.window addSubview:aView];
aView.frame = CGRectMake(0, 0, 320, 460);
[UIView animateWithDuration:0.5
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
aView.frame = endFrame;
}
completion:^(BOOL finished) {
[self dismissModalViewControllerAnimated:NO];
[aView removeFromSuperview];
}
];
This does result in a transition; but the previous view controller does not appear until after the animation since I can't dismiss until after it completes... any ideas?

Aah, when you presentModalViewController, it automatically hides the view behind. What you need to do is not present and remove, but add the view controllers view as a subview of the main view. Then you just animate the view offscreen, and removeFromSuperview in the competition handler.

Related

UIScrollView losing touch events

i have a scroll view in my application and i want that when the user scrolls it down, so its contentOffset.y reaches -50, the scroll view will animate to the bottom of the screen (at this point the scrollview won't be visible).
I managed to do this, but when i animate my scrollview back so it gets visible again it loses touch events and won't scroll anymore.
i already tried to set scrollEnabled and userInteractionEnabled to YES but nothing works. If someone could help i would appreciate.
Thanks.
This is the code when i animate my scroll view to the bottom of the screen
[UIView animateWithDuration:0.5 animations:^
{
CGRect scrollRect = self.scrollView.frame;
CGRect newFrame = CGRectMake(scrollRect.origin.x, 367, scrollRect.size.width, self.scrollView.contentSize.height);
self.scrollView.frame = newFrame;
}
completion:^(BOOL finished)
{
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)] autorelease];
}];
And this is the code where i make my scroll view visible again
[UIView animateWithDuration:0.5 animations:^
{
CGRect scrollRect = self.scrollView.frame;
CGRect newFrame = CGRectMake(scrollRect.origin.x, 0, scrollRect.size.width, self.scrollView.contentSize.height);
self.scrollView.frame = newFrame;
}
completion:^(BOOL finished)
{
self.navigationItem.leftBarButtonItem = nil;
self.scrollView.scrollEnabled = YES;
self.scrollView.userInteractionEnabled = YES;
_canScroll = YES;
}];
and after that i can't scroll it anymore.
You are setting scroll view height as self.scrollView.contentSize.height so scroll view will not be scrollable vertically.Try by changing it to self.scrollview.frame.height

Custom iPhone storyboard segue doesn't work properly

I want to load another view controller so the current slides up while the new one is coming from bottom, it works but I don't get the subviews (buttons disappear and I only get the blank view), how to fix it?
Current code is:
-(void)perform {
UIViewController *sourceVC = (UIViewController *) self.sourceViewController;
UIViewController *destinationVC = (UIViewController *) self.destinationViewController;
[UIView animateWithDuration:2.0
animations:^{
destinationVC.view.frame=CGRectMake(destinationVC.view.frame.origin.x, 480, destinationVC.view.frame.size.width, destinationVC.view.frame.size.height);
sourceVC.view.transform=CGAffineTransformMakeTranslation(0, -480);
destinationVC.view.transform=CGAffineTransformMakeTranslation(0, -480);
}];
}
You can create 2 views for your viewController, and set second view origin.y = window.height
Then animate like this -
CGRect outFrame = CGRectMake(0, 320, 320, 322);
[UIView animateWithDuration:0.50f
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
fromView.frame = outFrame;
toView.frame = CGRectMake(0, 0, 320, 322);
} completion:nil];
something like this...

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.

How to remove navigation bar from splash screen?

I have problem that is in my code i create splash screen for a time interval. When it execute then on the top of view a navigation bar is appeared. Now i want to hide that navigation bar. How i remove for that splash screen?
- (void)loadView {
// Init the view
//CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
CGRect appFrame = CGRectMake(0, 0, 320, 480);
UIView *view = [[UIView alloc] initWithFrame:appFrame];
view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.view = view;
[view release];
splashImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"LS.jpg"]];
splashImageView.frame = CGRectMake(0, 44, 320, 460);
[self.view addSubview:splashImageView];
viewController = [[Menu alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:viewController];
viewController.view.alpha = 0.0;
[self.view addSubview:nc.view];
timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(fadeScreen) userInfo:nil repeats:NO];}
-(void) onTimer{
NSLog(#"LOAD");
}
- (void)fadeScreen{
[UIView beginAnimations:nil context:nil]; // begins animation block
[UIView setAnimationDuration:0.75]; // sets animation duration
[UIView setAnimationDelegate:self]; // sets delegate for this block
[UIView setAnimationDidStopSelector:#selector(finishedFading)]; // calls the finishedFading method when the animation is done (or done fading out)
self.view.alpha = 0.0; // Fades the alpha channel of this view to "0.0" over the animationDuration of "0.75" seconds
[UIView commitAnimations]; // commits the animation block. This Block is done.
}
- (void) finishedFading{
[UIView beginAnimations:nil context:nil]; // begins animation block
[UIView setAnimationDuration:0.75]; // sets animation duration
self.view.alpha = 1.0; // fades the view to 1.0 alpha over 0.75 seconds
viewController.view.alpha = 1.0;
[UIView commitAnimations]; // commits the animation block. This Block is done.
[splashImageView removeFromSuperview];
}
You can hide the navigation bar by self.navigationController.navigationBar.hidden = YES;
The "Default" Splash Screen:
Using the Default.png image functionality of iOS is a great alternative for Splash Screens. Just add an image named "Default.png"('D' should be uppercase) to your project and the OS will take care of the rest.
In the splash view controller, add this to viewDidLoad.
self.navigationController.navigationBar.hidden = YES;
I would rather add the navigationcontroller's view to the window instead of the splash view controllers view. Also change the frame of the splash image to have a height of 480. You can also go for Default.png as #EmptyStack suggested
In the Info.plist you can add the property "Status bar is initially hidden" to YES and the status bar is gone forever!

Creating a faded out screen effect iphone

I have a view controller....when the user presses a button I want a black screen to fade in over the top and a uiactivityindicator to appear on top of the faded screen.
How can I get this animated fade in effect?
-(IBAction) loginToApp:(id)sender{
//fade in view
}
Add another view over the top of your view, colored solid black. You can do it in IB or programatically, just make sure it has a higher z-order (is on top). Make its alpha = 0. Then:
-(IBAction) loginToApp:(id)sender{
[UIView animateWithDuration:1.5 animations:^{ myview.alpha = 1.0; }]
}
...obviously you need an outlet or variable myview connected to that view. 1.5 = seconds. Change for your needs.
Sure you can. You can create the overlay view however you wish, but this will work (assuming you create appropriate instance variables somewhere). My code was in my view controller, so [self view] returns the view I want to shade over.
shadeView = [[UIView alloc] initWithFrame:[[self view] bounds]];
shadeView.backgroundColor = [UIColor blackColor];
shadeView.alpha = 0.0f;
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorStyleWhiteLarge];
spinner.center = CGPointMake(CGRectGetMidX([shadeView bounds]),
CGRectGetMidY([shadeView bounds]));
[shadeView addSubview:spinner];
[[self view] addSubview:shadeView];
To present:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[spinner startAnimating];
shadeView.alpha = 0.7f;
[UIView commitAnimations];
And to hide:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[spinner stopAnimating];
shadeView.alpha = 0.0f;
[UIView commitAnimations];