Objective C: Triggering IBAction showInfo in viewDidAppear - objective-c

I created my app using Utility Application template in Xcode 4.
I want my app to display the flip side on the first launch so that the user can enter a URL.
In my mainViewController I have:
- (void)viewDidAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if(![defaults stringForKey:#"url"]){
// Flip to the back page
[self showInfo: self];
NSLog(#"No url, flip");
}else{
NSLog(#"dont flip");
}
}
- (IBAction)showInfo:(id)sender
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
"No url, flip" is logged, and the showInfo method is called, but it does not flip.
What am I doing wrong?

just edit one line in your code.
- (void)viewDidAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if(![defaults stringForKey:#"url"]){
// Flip to the back page
[self performSelector:#selector(showInfo:) withObject:self afterDelay:0.1];
NSLog(#"No url, flip");
}else{
NSLog(#"dont flip");
}
}

Your showInfo: method is on the right track, sort of, but isn't going to work, I think. Here is an example of some code I have in an app that does what you're after, I believe:
PersonDetailViewController *pvc = [[PersonDetailViewController alloc]
initWithNibName:#"PersonDetailView" bundle:nil];
UIView *container = self.parentViewController.tabBarController.view;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:container cache:YES];
[container addSubview:pvc.view];
[pvc viewWillAppear:YES];
[self viewWillDisappear:YES];
[UIView commitAnimations];
The point of all this is that you have to give more info about the transition you are hoping to achieve. There are a number of UIView class methods (as shown here) that deal with setting up view transitions and other view-based animations.
So what's this doing? The code is adding the new view controller's view (pvc.view) as a subview of "container". In this app, the "container" view is the view that gets flipped out of the way as the new view (pvc.view) gets flipped in.
It is also important to call both the new view's viewWillAppear: and the old view's viewWillDisapear: so all the right stuff that you expect to happen when views come and go, happens. [This recipe may be considered "old school" by some. In the iPhone OS 2.x days (it wasn't called iOS back then), the Utility template had code similar to this, calling viewWillAppear and viewWillDisappear, etc. It still works today, fwiw. And the code shown here is in a shipping application on the app store, so its still kosher, so to speak. :-) ]
It is worth noting that in PersonDetailViewController (in this example) there is similar code that flips everything back, for consistency.

Related

Why is my UIViewController being loaded twice? iOS7

I am presenting my custom UIViewController (called "temp") with a custom animation. The UIVC gets called with:
[temp setModalPresentationStyle:UIModalPresentationCustom];
temp.transitioningDelegate = self;
[temp.view setHidden:YES];
[self presentViewController:temp animated:YES completion:nil];
My custom animation is presenting a view modally from right to top-left position of the screen. It is being presented hidden so the user doesn't see the animation. After it reaches the SCREEN_HEIGHT (768) position it is being set to visible and animated (moved) from top to bottom being presented in the middle. The goal was to present a view from top to bottom and dismiss it from top to bottom (like a movie scene). This code is the NOT working one:
- (void)animateTransition:(id)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
NSLog(#" fromViewController %# ",fromViewController);
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
NSLog(#" toViewController %# ",toViewController);
UIView *containerView = [transitionContext containerView];
if (self.presenting)
{
// set starting rect for animation toViewController.view.frame = [self rectForDismissedState:transitionContext];
[containerView addSubview:toViewController.view];
[UIView animateWithDuration:0.5
animations:^{
toViewController.view.frame = CGRectMake(-self.customSize.width, self.yValue, self.customSize.width, self.customSize.height);
}
completion:^(BOOL finished)
{
//HERE IS THE PROBLEM!!!
[toViewController.view setHidden:NO];
[UIView animateWithDuration:[self transitionDuration:transitionContext]
animations:^{
CGRect variable = [self rectForPresentedState:transitionContext];
CGRect fitToCurrentScreenResolution = CGRectMake(0, 0, variable.size.width, variable.size.height);
toViewController.view.frame = fitToCurrentScreenResolution;
}
completion:^(BOOL finished)
{
[transitionContext completeTransition:YES];
}];
}];
}
else
{
[UIView animateWithDuration:[self transitionDuration:transitionContext]
animations:^{
fromViewController.view.frame = [self rectForDismissedState:transitionContext];
}
completion:^(BOOL finished)
{
[transitionContext completeTransition:YES];
[fromViewController.view removeFromSuperview];
}
];
}
}
And here is the solution:
- (void)animateTransition:(id)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
NSLog(#" fromViewController %# ",fromViewController);
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
NSLog(#" toViewController %# ",toViewController);
UIView *containerView = [transitionContext containerView];
if (self.presenting)
{
// set starting rect for animation toViewController.view.frame = [self rectForDismissedState:transitionContext];
[containerView addSubview:toViewController.view];
[UIView animateWithDuration:0.5
animations:^{
toViewController.view.frame = CGRectMake(-self.customSize.width, self.yValue, self.customSize.width, self.customSize.height);
}
];
[toViewController.view setHidden:NO];
[UIView animateWithDuration:[self transitionDuration:transitionContext]
animations:^{
CGRect variable = [self rectForPresentedState:transitionContext];
CGRect fitToCurrentScreenResolution = CGRectMake(0, 0, variable.size.width, variable.size.height);
toViewController.view.frame = fitToCurrentScreenResolution;
}
completion:^(BOOL finished)
{
[transitionContext completeTransition:YES];
}];
}
else
{
[UIView animateWithDuration:[self transitionDuration:transitionContext]
animations:^{
fromViewController.view.frame = [self rectForDismissedState:transitionContext];
}
completion:^(BOOL finished)
{
[transitionContext completeTransition:YES];
[fromViewController.view removeFromSuperview];
}
];
}
}
My question is simple. Why is my UIVC being presented twice?
I have tried making my custom UIVC a property which is lazy loaded but my app crashes saying that a UIVC = nil can not be presented modally.
I have tried this solution, but it didn't apply to my problem :viewWillAppear being called twice in iOS5
I also did this with no help: Calling presentModalViewController twice?
I could have used a hack but I wouldn't find out why it is happening. So far it seems that when the animation enters the completion BLOCK it calls the view again.
The apple docs say:
A block object to be executed when the animation sequence ends. This
block has no return value and takes a single Boolean argument that
indicates whether or not the animations actually finished before the
completion handler was called. If the duration of the animation is 0,
this block is performed at the beginning of the next run loop cycle.
This parameter may be NULL.
Is the view being drawn again since the next run loop cycle is being started?
NOTE: Even thought the view is being presented twice, the viewDidLoad method is being called only once.
I would like to know why this is happening. There are some stackoverflow questions with the same code but with different usage scenarios having the same problem without a working solution or explanation.
Thank you for any advice/comment.
iOS 8.0, Xcode 6.0.1, ARC enabled
Yeah you are definetely onto it with "chained animation" (see comment from O.P.).
I witnessed a similar problem trying to hide and show the UIStatusBar for various UIViewControllers in my application, e.g. I have a dummy after load screen UIViewController that shows the same image as the load screen, but it has some added animations.
I am using a custom transition, which features a UIViewController that handles the transition from the "from" UIViewController and the "to" UIViewController by adding or removing their views from itself and assigning the "to" UIViewController "control" to itself. So on and so forth.
In the app. delegate,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
I had to instantiate the "initial view controller" and then initialize the transition UIViewController with it. Since there are no "to" UIViewControllers the transition UIViewController must hold an initial UIView of the UIViewController it was initialized with until a transition is triggered.
This was done utilizing,
self.window.rootViewController = self.transitionViewController;
[self.window makeKeyAndVisible];
After the very first transition, there always two UIViews overlaid onto each other. And two UIViewControllers one existing as the current control for the transition UIViewController that was assigned during the transition and the previous UIViewController that remains until the transition completes.
This was the code I was trying to use to show/hide the UIStatusBar, one must have the "View controller-based status bar appearance" set to "YES" in the *-Info.plist file.
- (void)viewDidLoad
{
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
}
- (BOOL)prefersStatusBarHidden
{
return false;
}
Whenever the "return" value was changes from default "false" to "true" regardless of when
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
was triggered, delay, no delay, conditional, etc.; both UIViewControllers, the "to" and "from" were reloaded. At first this was not noticeable, however after implementing an NSURLSession in one of the UIViewControllers that was triggered in the - (void)ViewDidLoad; the problem was clear. The session was executed twice and the graphical content involved was also updated.
I successfully solved the issue in two ways, however I kept the 2nd.
I put everything in -(void)ViewDidLoad; in an if statement and forced it to only be executed once, using an instance variable boolean. The -(void)ViewDidLoad; still loaded twice, however, things that I did not want to execute twice did not.
I transitioned to the UIViewController at which the UIStatusBar hidden state needed to change without using my transitional UIViewController. After the UIStatusBar was shown or hidden, I would reset the "rootViewController" for the app. delegate, once again assigning the transitional UIViewController as always "shown".
I describe how to do this in the following post: https://stackoverflow.com/a/26403108/4018041
Thanks. Hope this helps someone. Please comment on how this could be handled in the future for either the OP or myself.

Unbalanced calls to begin/end appearance transitions for <xxViewController: 0xaa82610>

I tried to add TapforTap Ads to my iPhone app, the ad appear but I show this message in console "Unbalanced calls to begin/end appearance transitions for ." after any navigation of pages and then the app crash, the below code for calling TapForTap Ads. How I can solve this problem?
- (void)viewDidLoad
{
[super viewDidLoad];
CGFloat y = self.view.frame.size.height - 50.0;
TapForTapAdView *adView = [[TapForTapAdView alloc] initWithFrame: CGRectMake(0, y, 320, 50) delegate: self];
[self.view addSubview: adView];
[TapForTapAppWall prepare];
[TapForTapAppWall showWithRootViewController: self]; // or possibly self.navigationController
}
Thanks A lot
I don't know it for sure. But try this:
- (void) ShowTapAd {
CGFloat y = self.view.frame.size.height - 50.0;
TapForTapAdView *adView = [[TapForTapAdView alloc] initWithFrame: CGRectMake(0, y, 320, 50) delegate: self];
[self.view addSubview: adView];
[TapForTapAppWall prepare];
[TapForTapAppWall showWithRootViewController: self]; // or possibly self.navigationController
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelectorOnMainThread:#selector(showTapAd) withObject:nil waitUntilDone:NO];
}
The run time warning that you got appears when you hussle with two (or more) segue, Navigation Controller push or present modally types of processes. Meaning when you initiate one before the former was totally finished.
I am surprised that those things can happen when you call something within viewDidLoad. So you may find out that the root cause is not located within the code sniplet that you have shown. But if it is then this could do the trick.
What it does:
It just makes sure that your setup of the ad view is performed after viewDidLoad is properly finished. As viewDidLoad runs on the main tread as all UI related stuff does (or should do), the current appearance transistion should be finised by then.
Hope, this helps. Again, it is just a guess.

UIPageViewControllerSpineLocation Delegate Method Not Firing

Major head-scratcher all day on this one :-(
I have an instance of a UIPageViewController that does not appear to be firing the delegate method:
-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
I have tried various methods of displaying the UIPageViewController and have settled on a programatic approach (as opposed to a Storyboard one) that appears to be working correctly, with one exception... when rotating the iPad to landscape the spine does not appear mid-point as expected. I simply cannot find out why the delegate method does not get called.
Code Explanation (simplified for example)
Consider three classes as follows:
RootViewController - loaded when the app starts
PageViewController - loaded by RootViewController upon user initiation
PageContentViewController - loaded by PageViewController when pages are needed
Fairly self-explanatory. The RootViewController is loaded by the app upon launch. When the user taps an image within this view controller's view (think magazine cover opening a magazine) it launches the PageViewController as follows:
PageViewController *pvc = [[PageViewController alloc] initWithNibName:#"PageView"
bundle:[NSBundle mainBundle]];
pvc.view.frame = self.view.bounds;
[self.view addSubview:pvc.view];
In the actual app there is animation etc to make the transition all nice, but essentially the PageViewController's view is loaded and takes fullscreen.
PageViewController
This is the workhorse (only relevant methods shown). I have tried various examples from the infinite world of Google and written directly from the Apple docs...
#interface PageViewController : UIViewController <UIPageViewControllerDelegate, UIPageViewControllerDataSource>
#property (nonatomic, strong) UIPageViewController *pageViewController;
#property (nonatomic, strong) NSMutableArray *modelArray;
#end
#implementation TXCategoryController
-(void)viewDidLoad
{
[super viewDidLoad];
// Simple model for demo
self.modelArray = [NSMutableArray alloc] init];
for (int i=1; i<=20; i++)
[self.modelArray addObject:[NSString stringWithFormat:#"Page: %d", i]];
self.pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.delegate = self;
self.pageViewController.dataSource = self;
PageContentViewController *startupVC = [[PageContentViewController alloc] initWithNibName:#"PageContent" bundle:nil];
startupVC.pageLabel = [self.modelArray objectAtIndex:0];
[self.pageViewController setViewControllers:[NSArray arrayWithObject:startupVC]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
self.pageViewController.view.frame = self.view.bounds;
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController
{
// Relevant code to add another view...
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController
{
// Relevant code to add another view...
}
-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
// Setting a break point in here - never gets called
if (UIInterfaceOrientationIsPortrait(orientation))
{
// Relevant code to create view...
return UIPageViewControllerSpineLocationMin;
}
// Relevant code to create 2 views for side-by-side display and
// set those views using self.pageViewController setViewControllers:
return UIPageViewControllerSpineLocationMid
}
#end
This all works perfectly well as I mentioned earlier. The PageViewController's view gets shown. I can swipe pages left and right in both portrait and landscape and the respective page number appears. However, I don't ever see two pages side-by-side in landscape view. Setting a breakpoint in the spineLocationForInterfaceOrientation delegate method never gets called.
This is such a head-scratcher I have burned out of ideas on how to debug/solve the problem. It almost behaves like the UIPageViewController isn't responding to the orientation changes of the device and therefore isn't firing off the delegate method. However, the view gets resized correctly (but that could be just the UIView autoresizing masks handling that change).
If I create a brand new project with just this code (and appropriate XIb's etc) it works perfectly fine. So something somewhere in my actual project is causing this. I have no idea where to continue looking.
As usual, any and all help would be very much appreciated.
Side Note
I wanted to add the tag 'uipageviewcontrollerspinelocation' but couldn't because it was too long and I didn't have enough reputation (1500 required). I think this is a devious ploy on Apple's part to avoid certain tags in Stackoverflow... ;-)
Finally found the problem. It was something of a red herring in its symptoms, but related just the same.
Putting a break point in the shouldAutorotateToInterfaceOrientation: method was a natural test to see if the UIViewController was even getting a rotation notification. It wasn't which led me to Apple's technical Q&A on the issue: http://developer.apple.com/library/ios/#qa/qa1688/_index.html
The most relevant point in there was:
The view controller's UIView property is embedded inside UIWindow but alongside an additional view controller.
Unfortunately, Apple, in its traditional documentation style, doesn't provide an answer, merely confirmation of the problem. But an answer on Stack Overflow yielded the next clue:
Animate change of view controllers without using navigation controller stack, subviews or modal controllers?
Although my RootViewController was loading the PageViewController, I was doing it as a subview to the main view. This meant I had two UIViewController's in which only the parent would respond to changes.
The solution to get the PageViewController to listen to the orientation changes (thus triggering the associated spine delegate method) was to remove addSubview: and instead present the view controller from RootViewController:
[self presentViewController:pac animated:YES completion:NULL];
Once that was done, the orientation changes were being picked up and the PageViewController was firing the delegate method for spine position. Only one minor detail to consider. If the view was launched in landscape, the view was still displaying portrait until rotated to portrait and back to landscape.
That was easily tweaked by editing viewDidLoad as follows:
PageContentViewController *page1 = [[PageContentViewController alloc] initWithNibName:#"PageContent" bundle:nil];
NSDictionary *pageViewOptions = nil;
NSMutableArray *pagesArray = [NSMutableArray array];
if (IS_IPAD && UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
pageViewOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:UIPageViewControllerSpineLocationMid]
forKey:UIPageViewControllerOptionSpineLocationKey];
PageContentViewController *page2 = [[PageContentViewController alloc] initWithNibName:#"PageContent" bundle:nil];
[pagesArray addObject:page1];
[pagesArray addObject:page2];
}
else
{
[pagesArray addObject:page1];
}
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:pageViewOptions];
self.pageViewController.delegate = self;
[self.pageViewController setViewControllers:pagesArray
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
Job done and problem solved.

UIViewController transition - objective-c

I have UIViewControllers A and B, they are allocated in AppDelegate. I need to apply transition to them. How to transit them without reallocating and replacing UIViews?
This code calls from my UIBarButtonItem in UINavigationController:
[UIView transitionFromView:self.view //UIViewController A
toView:appDelegate.secondViewController.view //UIViewController B
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
This method replaces UIViews in my UIViewControllers, and I can transit them back, or just don't know how to do that. Can you tell me how to do this?
If you're in iOS 5 world and want to jump between various view controllers, you might want to pursue View Controller Containment. Or check out WWDC 2011 session 102.
View controller containment basically assumes that you have some parent view controller which is governing the navigation between multiple child controllers. In your case, the parent view would be one with the navigation bar with the button on it.
Update:
If you pursue containment, you could create a parent view controller that has a nav bar with the button on it. When you load that view, you can add the first child view. Thus viewDidLoad might look like:
- (void)viewDidLoad
{
[super viewDidLoad];
// this is my model, where I store data used by my view controllers
_model = [[MyModel alloc] init];
// let's create our first view controller
OneViewController *controller = [[OneViewController alloc] initWithNibName:#"OneViewController" bundle:nil];
// pass it our model (obviously, `model` is a property that I've set up in my child controllers)
controller.model = _model;
// let's put the new child in our container and add it to the view
[self addChildViewController:controller];
[self configureChild:controller];
[self.view addSubview:controller.view];
[controller didMoveToParentViewController:self];
// update our navigation bar title and the label of the button accordingly
[self updateTitles:controller];
}
The configureChild just does final configuration. As a matter of convenience, I frequently will have a UIView that I've set up in IB (in this case, called childView) which I use for setting up the frame, which gets me out of the world of manually creating frames, but you can do it any way you want:
- (void)configureChild:(UIViewController *)controller
{
// configure it to be the right size (I create a childView in IB that is convenient for setting the size of the views of our child view controllers)
controller.view.frame = self.childView.frame;
}
This is the action if you touch the button in the navigation bar. If you're in the first controller, set up the second controller. If you're in the second controller, set up the first one:
- (IBAction)barButtonTouchUpInside:(id)sender
{
UIViewController *currentChildController = [self.childViewControllers objectAtIndex:0];
if ([currentChildController isKindOfClass:[OneViewController class]])
{
TwoViewController *newChildController = [[TwoViewController alloc] initWithNibName:#"TwoViewController" bundle:nil];
newChildController.model = _model;
[self transitionFrom:currentChildController To:newChildController];
}
else if ([currentChildController isKindOfClass:[TwoViewController class]])
{
OneViewController *newChildController = [[OneViewController alloc] initWithNibName:#"OneViewController" bundle:nil];
newChildController.model = _model;
[self transitionFrom:currentChildController To:newChildController];
}
else
NSAssert(FALSE, #"Unknown controller type");
}
This does the basic transition (including the various containment related calls):
- (void)transitionFrom:(UIViewController *)oldController To:(UIViewController *)newController
{
[self addChildViewController:newController];
[self configureChild:newController];
[self transitionFromViewController:oldController
toViewController:newController
duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self updateTitles:newController];
}
completion:^(BOOL finished){
[oldController willMoveToParentViewController:nil];
[oldController removeFromParentViewController];
[newController didMoveToParentViewController:self];
}];
}
This method just sets up the title in the nav bar in our parent view controller based upon which child is selected. It also sets up the button to reference the other controller.
- (void)updateTitles:(UIViewController *)controller
{
if ([controller isKindOfClass:[OneViewController class]])
{
self.navigationItemTitle.title = #"First View Controller"; // current title
self.barButton.title = #"Two"; // title of button to take me to next controller
}
else if ([controller isKindOfClass:[TwoViewController class]])
{
self.navigationItemTitle.title = #"Second View Controller"; // current title
self.barButton.title = #"One"; // title of button to take me to next controller
}
else
NSAssert(FALSE, #"Unknown controller type");
}
This all assumes you are going to create and destroy controllers as you jump between them. I generally do this, but use a model object to store my data so I keep whatever data I want.
You said you don't want to do this "without reallocating and replacing UIViews": If so, you can also change the above code to create both child view controllers up-front and change the transition to be simply jump between them:
- (void)viewDidLoad
{
[super viewDidLoad];
// this is my model, where I store data used by my view controllers
_model = [[MyModel alloc] init];
// let's create our first view controller
_controller0 = [[OneViewController alloc] initWithNibName:#"OneViewController" bundle:nil];
_controller0.model = _model;
[self addChildViewController:_controller0];
[self configureChild:_controller0];
[_controller0 didMoveToParentViewController:self];
// let's create our second view controller
_controller1 = [[OneViewController alloc] initWithNibName:#"OneViewController" bundle:nil];
_controller1.model = _model;
[self addChildViewController:_controller1];
[self configureChild:_controller1];
[_controller1 didMoveToParentViewController:self];
// let's add the first view and update our navigation bar title and the label of the button accordingly
_currentChildController = _controller0;
[self.view addSubview:_currentChildController.view];
[self updateTitles:_currentChildController];
}
- (void)transitionFrom:(UIViewController *)oldController To:(UIViewController *)newController
{
[self transitionFromViewController:oldController
toViewController:newController
duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self updateTitles:newController];
}
completion:^(BOOL finished){
_currentChildController = newController;
}];
}
- (IBAction)barButtonTouchUpInside:(id)sender
{
UIViewController *newChildController;
if ([_currentChildController isKindOfClass:[OneViewController class]])
{
newChildController = _controller1;
}
else if ([_currentChildController isKindOfClass:[TwoViewController class]])
{
newChildController = _controller0;
}
else
NSAssert(FALSE, #"Unknown controller type");
[self transitionFrom:_currentChildController To:newChildController];
}
I've seen it both ways, so you can do whatever works for you.
please see here. You basically want to implement UIViewController containment which is a new feature in iOS5. The link provided above provides some code and a link to a github project.
Good luck
t
I found solution for my problem. This code works on iOS 4.x
[UIView beginAnimations:#"transition" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown
forView:self.navigationController.view
cache:NO];
[self.navigationController
pushViewController:self.alternateView animated:NO];
[UIView commitAnimations];
try
UIViewController* controller1;
UIViewController* controller2;
[controller1 transitionFromViewController:controller1 toViewController:controller2 duration:0.5f options:0 animations:nil completion:nil];
or
if on top of navigationtroller - controller1 then
UINavigationController* nav;
[nav pushViewController:controller2 animated:YES];

- (void)viewWillAppear:(BOOL)animated detect custom animation

I have a button which when pressed pushes a view controller however i'm using a custom animation so pushViewController: childController animated: is set to NO. What i want to do though is detect this custom animation in my - (void)viewWillAppear:(BOOL)animatedmethod and write an if statement like this;
- (void)viewWillAppear:(BOOL)animated {
if (customAnimation occured) {//Do this}
else {//Do this}
}
This is the method for my button which pushes the view controller.
- (void)nextPressed:(id)sender {
childController = [[CategoryOneDetailController alloc] initWithNibName:xibDownName bundle:nil];
[UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController: childController animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[childController release];
}
Any help would be much appreciated, thanks, Sami.
If you don't use standard animations, I think your best bet is to add a property to your pushed view controller that is set to YES in case of a custom animation (and NO by default to not break any existing behavior). Then you can check that property in viewDidAppear:.
If you need your custom logic to be executed after the animation has run, you might want to set up an animation completion handler or block.