change direction of segue of pushViewController in iPhone - iphone

I am using the following code to launch a view controller named secondViewController.
[self.navigationController pushViewController:secondViewController animated:YES];
The code successfully causes the secondVC to slide in from the right to left
After the user is done I would like the user to be able to go back to the first View Controller. For this purpose I have wired a back button to a method that uses similar code, however in this case I would like it to slide from left to right, i.e. the opposite direction. However, not surprisingly the return VC also goes from right to left.
[self.navigationController pushViewController:returnViewController animated:YES];
Is there a way to reverse the direction so that in the second case, it slides from left to right?
EDIT:
Using the code from the answer suggested by Brendan, I have added the following method to override the pushViewController. I am calling it the same way but have had to comment the swapButtonsForViewController as the selector SwapButtons is not recognized. Not sure what it really does.
In addition, if you call it as super, I get an error: no visible#interface in the super VC for this VC. Not sure how to fix that. If I change super to self, error disappears but it still goes right to left.
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
UIView *theWindow = self.view ;
if( animated ) {
CATransition *animation = [CATransition animation];
[animation setDuration:0.45f];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
[[theWindow layer] addAnimation:animation forKey:#""];
}
//make sure we pass the super "animated:NO" or we will get both our
//animation and the super's animation
[super pushViewController:viewController animated:NO];
// [self swapButtonsForViewController:viewController];
}

Oops, a few things in addition to my comment:
Did you inherit from UINavigationController? That will help, if you didn't do that already.
Also, the link I shared with you will replace the direction for both cases, unfortunately. I should have read the question more carefully, apologies.
Good news though! Try both of these:
https://stackoverflow.com/a/16535931/5806860
https://stackoverflow.com/a/16384808/5806860
Those are similar solutions, but have minor changes that could potentially solve your problem.

Related

UINavigationController popViewControllerAnimated: crash in iOS 6

The code below works fine in iOS 4 and 5 but crashes in iOS 6 with EXC_BAD_ACCESS. I'd appreciate any help in troubleshooting it. This code is being called in a UITableViewController that handles my app's search logic:
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionFade;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[self.navigationController popViewControllerAnimated:NO];
The way I add the tableView is similar and doesn't crash when called:
SearchTVC *searchTable = [[SearchTVC alloc] init];
searchTable.detailViewController = self.detailViewController;
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionFade;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[self.navigationController pushViewController:searchTable animated:NO];
What could be the problem?
*EDIT
Interestingly the crash doesn't occur if I use [self.navigationController popViewControllerAnimated:YES]; (YES rather than NO). But of course this defeats the purpose of using a custom pop animation.
Check whether you have a line like the following somewhere in your view controller code:
self.navigationController.delegate=self;
If so, then you must set it back
self.navigationController.delegate=nil;
before you say
[self.navigationController popViewControllerAnimated:YES];
Otherwise, popViewControllerAnimated will first deallocate the delegate and then try to call it - resulting in a crash.
I know my question was vague, but I didn't have much else to go off of. I knew the line [self.navigationController popViewControllerAnimated:NO]; was the problem but I couldn't figure out why. Then I came across this question and the first answer suggested I make my search table an instance variable rather than creating a new one every time I want to present it, and that actually worked. It must be a memory issue that I can't wrap my head around.
tl;dr :
Make sure the UIViewController that's being pushed and popped is an instance variable.
Though super late to party... Hope this might help someone in future.
I opened a very old code...
Enabling ARC mode and then resolving all the compiler warnings/error fixed it automatically.

iphone navigation model without uinavigation controller?

I am writing an app that needs to display a series of approximately 10-20 'views'. I have 4 view controllers and nibs that I would like to use. Each view has a forward and back button on it and the views should slide in either from the right or the left depending on the button pushed. I want to be able to reuse the nibs and controllers to present the information. I was trying to use a uinavigation controller, but ran into the problem that you can't push a view onto the stack more than once. The overall structure is a uinavigationcontroller within a tabbarcontroller. Is there a way to do this with a uinavigation controller, or should I try a different approach.
I would suggest making a container view controller class. It would create and "own" the four different view controllers you want to use. Then use something like this to switch between them:
// get the view that's currently showing
UIView *currentView = self.view;
// get the the underlying UIWindow, or the view containing the current view view
UIView *theWindow = [currentView superview];
// remove the current view and replace with newView
[currentView removeFromSuperview];
[theWindow addSubview:newView];
// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:#"SwitchToView1"];
(stolen from here)

Speeding up iPhone animations

I have a data entry application that has the user enter about 6 pieces of information all on different views in a navigation controller. This works fine, but once the user gets used to the application the time it takes for the next screen to appear slows the user down.
I tried the application without the animations, but it doesn't feel quite right. Is there a way to get the animations to occur quicker? I'm primarily using a navigation controller, table views, and picker views.
There's going to be a penalty each time you load a new view, you could attempt to consolidate screens using a scroll view or a different layout.
Also, if you are loading any unnecessary graphics you may want to remove them.
You could also add each view as a subview yourself in which case you have control over the animation duration among other things. This code will do that for you, although beware as I just wrote it and did not test it (The transition style and boolean parameters can be removed as they do nothing right now).
UIViewControllerExtendedPresentModalViewController.h
#import <Foundation/Foundation.h>
typedef enum _ExtendedModalTransitionStyle
{
ExtendedModalTransitionStyleTopDown
} ExtendedModalTransitionStyle;
#interface UIViewController ( ExtendedPresentModalViewController )
- (void)presentModalViewController: (UIViewController*)modalViewController
withTransitionStyle: (ExtendedModalTransitionStyle)style
animated: (BOOL)animated;
- (void)dismissModalViewController: (UIViewController*)modalViewController
withTransitionStyle: (ExtendedModalTransitionStyle)style
animated: (BOOL)animated;
#end
UIViewControllerExtendedPresentModalViewController.m
#import "UIViewControllerExtendedPresentModalViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation UIViewController ( ExtendedPresentModalViewController )
- (void)presentModalViewController: (UIViewController*)modalViewController
withTransitionStyle: (ExtendedModalTransitionStyle)style
animated: (BOOL)animated
{
[modalViewController retain]; // we'll need this for a little while, hang on to it.
CATransition* transition = [CATransition animation];
[transition setDuration: 0.4];
[transition setTimingFunction:
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear]];
[transition setType: kCATransitionMoveIn];
[transition setSubtype: kCATransitionFromBottom];
[[[self view] layer] addAnimation: transition
forKey: nil];
[[self view] addSubview: [modalViewController view]];
}
- (void)dismissModalViewController: (UIViewController*)modalViewController
withTransitionStyle: (ExtendedModalTransitionStyle)style
animated: (BOOL)animated
{
CATransition* transition = [CATransition animation];
[transition setDuration: 0.4];
[transition setTimingFunction:
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear]];//kCAMediaTimingFunctionEaseInEaseOut]];
[transition setType: kCATransitionReveal];
[transition setSubtype: kCATransitionFromTop];
[[[[modalViewController view] superview] layer] addAnimation: transition
forKey: nil];
[[modalViewController view] removeFromSuperview];
[modalViewController release]; // all done, we can let this go.
}
#end
Are you reusing cells in the table view? Make sure to really reuse them, in other words do all the setup of the cell inside the if(cell==nil) case and only apply the data in the common case (applying to both reuse and newly created).
Be aware of the performance hit that transparency can have in a cell. Often it seems that you have to make things transparent but maybe you don't because UITableViewCell is aware of the problems. Turning off transparency in some objects might seem wrong but is worth a try to see if it actually works. Most of the cost of scrolling a cell is the compositing as the cell moves, not creation of the cell initially.
Another thing that can help is doing the compositing of the view that you apply to your cell in advance rather than adding all the views to the cell, then you apply just one premade view to your cell.
If you are actually animating views in the scrolling cells you may need to rethink that or at least use some simplification to make it a little less taxing on the device.
You might also consider adopting Matt Gallagher's strategy for cell handling - it stops your cellForRowAtIndexPath turning into one long, nasty set of ifs.

iPhone SDK: Optimize UIModalTransitionStyleFlipHorizontal

I want to flip my new ModalView with very high performance, but the new View has a lot of subviews so the performance of the Flip-Effect is very bad. Actually i do it with:
[controller setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:backSideController animated:YES];
I also tried it with
CATransition *transition = [CATransition animation];
transition.duration = 0.75;
[transition setType: #"flip"];
[transition setSubtype:#"fromRight"];
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[transition setFillMode:#"extended"];
[[self.view layer] addAnimation:transition forKey:nil];
[self.view addSubview: backSideController.view];
[CATransaction commit];
With Core-Animation it works a little bit faster ... ware there further ways to opimize this task? e.g. Adding view when animation stops and just flipping a screenshot until animation stops?
Try accessing backsideController.view before you begin the animations. This will cause backsideController's loadView and viewDidLoad to be called. I'm guessing that this is your performance hit -- that all that loading & allocating is causing the animation to stutter.
You don't need anything fancy, you can do something like:
if (backsideController.view == nil)
NSLog(#"Where's my view?!");
before your other code, above.
I don't believe that having many-many subviews causes performance problems on the flip; I'm pretty sure (without looking at your code or checking in instruments, which you should do!) that the problem is the time it takes to load and allocate the view components.
Also, I'd stick with presentModalViewController, if it does what you want. Having all that extra code in your 2nd example -- unless it's needed for functionality -- is just maintenance headache.

Flip transition in iPhone

I am facing problems in flipping views in iPhone.
I have two views in appDelegate. I want to flip them once user clicks on a button.
I have the following code:
CATransition *transition = [CATransition animation];
transition.duration = 0.75;
[transition #"twist"];
[transition setSubtype:#"fromRight"];
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[transition setFillMode:#"extended"];
[[window layer] addAnimation:transition forKey:nil];
[window addSubview:self.s.view];
[CATransaction commit];
But this is not working. Do anybody knows a better way to flip the views on window side.
What I am doing is calling the method from appDelegate in the respective viewControllers to flip the views.
If you're using the 3.0 SDK and all you want is a simple flip transition (ala the Weather app) then you don't need to go down to CATransition. The higher-level UIView animation transitions will do what you want but with 3.0 there is an even easier way: simply present your new view as a modal view controller and set the modal transition style to flip. From within the first controller:
UIViewController *controllerForSecondView = ..;
controllerForSecondView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controllerForSecondView animated:YES];
Flip back again by using dismissModalViewController.
Documentation Reference
#Luke - thanks, this sample helped me...1 correction though (based on UIViewController.h)
UIViewController *controllerForSecondView = ..;
controllerForSecondView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controllerForSecondView animated:YES];
From the header file comments:
// Defines the transition style that will be used for this view controller when it is presented modally. Set this property on the view controller to be presented, not the presenter.
// Defaults to UIModalTransitionStyleSlideVertical.
#property(nonatomic,assign) UIModalTransitionStyle modalTransitionStyle
See The Elements sample code. Particularly AtomicElementViewController -flipCurrentView.