Switching view by changing delegate rootViewContoller - objective-c

I'm presently trying to switch view from a UIViewController to a SplitViewController. I'm currently doing this in my UIViewController:
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[UIView transitionWithView:delegate.window duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
delegate.window.rootViewController = delegate.splitViewController;
} completion:nil];
[self.view removeFromSuperview];
Is it the right way to switch view ? If yes, I still have a problem to solve with that method.
It first quickly shows the MasterView in Portrait Mode and then show the whole split view in the current orientation mode of the iPad.
I hope I'm clear enough.
Thank for you help.

I found a way to make it work from that thread :
RootViewController animation transition, initial orientation is wrong
AppDelegate *delegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
delegate.window.rootViewController = self.splitViewController;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];

Related

Fade effect when going from one viewController to other using Navigation Controller

How to achieve fade effect when going from one viewController to other using navigation Controller
normally we do to push :
DetailViewController *obj= [[DetailViewController alloc]initWithNibName:#"DetailView" bundle:nil];
[self.navigationController pushViewController:obj animated:YES];
and to pop :
UINavigationController *navController = self.navigationController;
// retain ourselves so that the controller will still exist once it's popped off
[[self retain] autorelease];
// Pop this controller and replace with another
[navController popViewControllerAnimated:YES];
But I want fading effect when I do pop or push .. plz suggest
this is not the exact code you want but you can get the way how to do the animation you want
First have to pass the parameter NO for any animation while push and pop view and have to give some custom animation like this
// Flash the screen white and fade it out to give UI feedback that a still image was taken
UIView *flashView = [[UIView alloc] initWithFrame:[[self videoPreviewView] frame]];
[flashView setBackgroundColor:[UIColor whiteColor]];
[[[self view] window] addSubview:flashView];
[UIView animateWithDuration:.4f
animations:^{
[flashView setAlpha:0.f];
}
completion:^(BOOL finished){
[flashView removeFromSuperview];
}
];
For more detail answer and use the block in proper way see this answer on other question on SO
Some of the code from that answer is as follow
For Push:
MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[super pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
For Pop:
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:self.navigationController.view cache:NO];
}];
[self.navigationController popViewControllerAnimated:NO];
Thanks to #ijordan
Some other tips for the problem is here
This one is one excellent example for your use no use to do extra coding with this as it provides category for animation of navigation controller.
I rewrote The iOSDev's solution (thanks!) in Swift 5+ (without deprecation warnings etc.):
Push:
UIView.transition(with: navigationController.view, duration: 0.5, options: [.transitionCrossDissolve], animations: {
self.navigationController.pushViewController(viewControllerToBeShown, animated: false)
}) { _ in
completion()
}
Pop:
UIView.transition(with: navigationController.view, duration: 0.5, options: [.transitionCrossDissolve], animations: {
self.navigationController.popViewController(animated: false)
}) { _ in
completion()
}

iOS transition animation for pushViewController

I have an AppDelegate, which owns a window, and from there on, A main view, from which when I go to the next view, I push the new view in order to use the same Navigation Controller and toolbar:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
self.appview = [[AppointmentView alloc] initWithNibName:#"AppointmentView" bundle:[NSBundle mainBundle]];
#synchronized(self.MahAppntmnts){ // Set the view's appointment
[appview setMyAppointment:[[MahAppntmnts MyAppointments] objectAtIndex:indexPath.section]];
}
[super addChildViewController:self.appview];
AppDelegate *del = (AppDelegate *)[UIApplication sharedApplication].delegate;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[del.navigationController pushViewController:self.appview animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
}
Now this works fine for switching views, but when I'm trying to go back, I get the same boring flip transition.
I tried setting on my AppView's viewWillDissapear delegate method:
-(void) viewWillDisappear:(BOOL)animated
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:0.375];
[self.navigationController popViewControllerAnimated:NO];
[UIView commitAnimations];
[super viewWillDisappear:animated];
}
This seems to work for when I go back to the previous view, but when I try to transition to new views (using the same method as before) they either not appear, or I flip by to the same view. So I'm guessing that this code should not be on viewWillDissapear, or that I am doing something wrong...
Well I found the solution, problem was my miss-conception to "whom" the animation belonged to. I added the code found in viewWillDissapear (located in the pushed view), to the viewWillAppear delegate of the view that did the pushing in the first place (the code found in accessoryButtonTappedForRowWithIndexPath), so that the controlling view initiates the animation when pushing another view, and when another view navigates back to it, the reverse animation is displayed. Solved all problems and works like a charm.

iOS - View not loading properly in iPad when rotating

I have created a simple iPad application with rotation support. It has two view controllers. First View Controller is loaded automatically as rootViewController of the AppDelegate. It has a button on it which, when clicked, changes the rootViewController of AppDelegate to Second View Controller. The Second View Controller has a button on it which sets rootViewController back to First View Controller. This work Perfectly in Portrait mode. But when I rotate the simulator to Landscape mode, and click on the button on First View Controller to load the Second View Controller, it first displays the Second View according to the device (un-rotated), and then rotates the display to normal (Landscape), after completing the animation. What is going wrong ?
The methods in AppDelegate to set View Controllers are as follows:
(void)loadSecondView
{
SecondView *secondViewController = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.window cache:YES ];
self.window.rootViewController = secondViewController;
[UIView commitAnimations];
}
(void) removeSecondView
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.window cache:YES ];
self.window.rootViewController = self.firstViewController;
[UIView commitAnimations];
}
Basically you're wrapping two operations inside an animation block.
making a new view controller as the root view
showing that view in a curl animation
As a result, you see two operations during your animation.
new view is added to the window, and it's rotated based on device's orientation
curl animation makes the new view visible
You can fix this problem by applying the following change:
- (void)loadSecondView {
SecondView *secondview = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
self.window.rootViewController = secondview;
self.window.rootViewController.view.hidden = YES;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.window cache:YES ];
self.window.rootViewController.view.hidden = NO;
[UIView commitAnimations];
}
- (void)removeSecondView {
self.window.rootViewController = self.viewController;
self.window.rootViewController.view.hidden = YES;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.window cache:YES ];
self.window.rootViewController.view.hidden = NO;
[UIView commitAnimations];
}
Basically, we're adding the view without any animation effect, and for transition animation, we're using view's hidden property.
HTH.

Custom Segue with UIViewAnimationOptionTransitionCurlDown

I'd like create a custom segue to swap ViewControllers with a curl up animation but I can't find a way, What would be the -(void)perform for this?
I've got this
-(void)perform{
UIViewController *dst = [self destinationViewController];
UIViewController *src = [self sourceViewController];
[UIView beginAnimations:nil context:nil];
//change to set the time
[UIView setAnimationDuration:1];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:src.view cache:YES];
[UIView commitAnimations];
}
But I don't get to change the view, anyway thanks for your help!
Nevermind, I solved it, for the record the only thing I had to do was add a Navigation Controller and then I could use custom segues like:
- (void) perform {
UIViewController *src = (UIViewController *) self.sourceViewController;
UIViewController *dst = (UIViewController *) self.destinationViewController;
[UIView transitionWithView:src.navigationController.view duration:0.3
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:^{
[src.navigationController pushViewController:dst animated:NO];
}
completion:NULL];
}

UIViewAnimationTransitionCurl in left and right direction

Is there any way possible to use UIViewAnimationTransitionCurl in left and right directions? I'm looking for something similar to the Contacts app:
If you are targetting iOS 5, use UIPageViewController. The last fifteen minutes of the Implementing UIViewController Containment video from WWDC 2011 describe how to use it.
If you don't mind iOS 5 as a requirement you could use the new UIPageViewController
Otherwise you could try something like this:
self.appDelegate = [[UIApplication sharedApplication] delegate];
UIViewController *srcViewController = (UIViewController *) self.sourceViewController;
UIViewController *destViewController = (UIViewController *) self.destinationViewController;
[UIView commitAnimations];
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:self.appDelegate.window.rootViewController.view.superview cache:YES];
[srcViewController.view removeFromSuperview];
[UIView commitAnimations];
[self.appDelegate.window addSubview:destViewController.view];
self.appDelegate.window.rootViewController=destViewController;
Cheers....