Create a UINavigationController For present 2 UIViewController in Objective-C - ios

I have 2 UIViewControllers and want to have UINavigationController with UINavigationBar & UINavigationItem on them. But my code doesn't working ..
here is my code :
#import "testView1.h"
#import "testView2.h"
#interface testView1 ()
#end
#implementation testView1
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor darkGrayColor];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self];
testView2 *detail = [testView2 new];
[navController pushViewController:detail animated:YES];
}

Try to embed navigation controller in storyboard as below :
First select your testView1 in storyboard .
Select Navigation Controller
And Changes as below
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
/// testView2 *detail = [testView2 new];
testView2 *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"testView2 Identifier"]; // if you have add controller in storyboard
[self.navigationController pushViewController:detail animated:YES];
}

You won't see the first View Controller because you already push the second view controller upon the navigation controller.

Related

UINavigationController title in iOS seems corrupted

When I present a UINavigationController modally and then push (without animation) some UIViewcontrollers onto it, the finally shown navigationItem.title is different from what I would expect.
I tried to narrow my issue down and came up with the following short code to duplicate the issue:
#implementation DummyRootVC
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:[[Dummy1VC alloc] init]];
[self presentViewController:nc
animated:false
completion:nil];
}
#end
#implementation Dummy1VC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor whiteColor];
self.navigationItem.title= #"DUMMY1";
[self.navigationController pushViewController:[[Dummy2VC alloc] init]
animated:false];
}
#end
#implementation Dummy2VC
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title= #"DUMMY2";
self.view.backgroundColor=[UIColor yellowColor];
[self.navigationController pushViewController:[[Dummy3VC alloc] init]
animated:false];
}
#end
#implementation Dummy3VC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor orangeColor];
self.navigationItem.title= #"DUMMY3";
[self.navigationController pushViewController:[[Dummy4VC alloc] init]
animated:false];
}
#end
#implementation Dummy4VC
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title= #"DUMMY4";
self.view.backgroundColor=[UIColor greenColor];
for (UIViewController* vc in self.navigationController.viewControllers) {
NSLog(#"VC Stack: %# Title:%#",vc,vc.navigationItem.title);
}
NSLog(#"End");
}
#end
In AppDelegate I set:
self.window.rootViewController = [[DummyRootVC alloc] init];
When running that code the displayed title is „Dummy 2“ and the back-button is named „Dummy 4“, while I actually would expect a title „Dummy 4“ and a back-button named „Dummy 3“.
The log shows as expected the correct ViewController-Stack and the backgroundColor is (as expected) green (and interestingly is still green after one "back" click):
VC Stack: Title:DUMMY1
VC Stack: Title:DUMMY2
VC Stack: Title:DUMMY3
VC Stack: Title:DUMMY4
End
I could work around that issue since it seems somewhat related to the non-animation setting in combination with presenting the navigation controller modally, but I would like to understand the underlying issue…
Can anyone provide me with some insight? Is this some bug or am I doing (as I suspect) just something the wrong way?
Thanks!
Put the push/present from viewDidLoad to viewWillAppear or viewDidAppear so that the viewController can init it's subview correctly to avoid problem :D

Resize Navigation Controller presented modally UIModalPresentationFormSheet as each new view controller is pushed

Setup: 'VC1' creates 'NavigationVC' with a root view controller 'VC2' and presents it modally with presentation style UIModalPresentationFormSheet. 'VC2' shows up inside the nav controller in the middle of the screen with the correct size.
Issue: As I continue to push view controllers onto the modal NavVC I would like them to resize. NSLog of my preferredContentSize in each view controller that is pushed verifies that my constraints are correct and the sizes are in fact different. However I have experimented extensively and have not figured out how to change the size of the modal after it has been presented.
#implementation VC1()
- (void) viewDidLoad{
VC1* vc1 = [self getNextVC];
NavVC* navVC = [[UINavigationViewController alloc] initWithRootViewController:vc1];
[navVC setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:navVC animated:YES completion:nil];
}
#end
#implementation NavVC()
- (CGSize) preferredContentSize{
CGSize size = [[self topViewController] preferredContentSize];
return size;
}
#end
#implementation VC2()
- (CGSize) preferredContentSize{
CGSize size = [[self view] systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size;
}
#end
I’ve spent some time dealing with the same problem. Pushing the view controller on modal navigation controller for iOS8 resulted in having the view controller with the same size as the root view controller, while for iOS7 this second view controller had the default size of modal form sheet (540.f, 620.f). The only working solution, I could come up with so far, for both iOS7 and iOS8 is as follows:
ViewController1.m
#interface ViewController1 ()
#end
#implementation ViewController1
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.bounds = CGRectMake(0, 0, VC1_WIDTH, VC1_HEIGHT);
}
- (void)nextTapped:(id)sender {
ViewController2 *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[self.navigationController pushViewController:vc2 animated:NO];
// call after push
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC2_WIDTH,VC2_HEIGHT);
}
#end
Presenting ViewController1:
ViewController1 *vc1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:vc1];
navVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navVC animated:NO completion:nil];
ViewController2.m
#import "ViewController2.h”
#interface ViewController2 ()
#end
#implementation ViewController2
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.bounds = CGRectMake(0, 0, VC2_WIDTH, VC2_HEIGHT);
}
- (void)nextTapped:(id)sender {
ViewController3 *vc3 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController3”];
[self.navigationController pushViewController:vc3 animated:NO];
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC3_WIDTH,VC3_HEIGHT);
}
- (void)backTapped:(id)sender {
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC1_WIDTH,VC1_HEIGHT);
[self.navigationController popViewControllerAnimated:NO];
}
#end
ViewController3.m
#import "ViewController3.h”
#interface ViewController3 ()
#end
#implementation ViewController3
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.bounds = CGRectMake(0, 0, VC3_WIDTH, VC3_HEIGHT);
}
- (void)backTapped:(id)sender {
self.navigationController.view.superview.bounds = CGRectMake(0, 0,VC2_WIDTH,VC2_HEIGHT);
[self.navigationController popViewControllerAnimated:NO];
}
#end
Please note, if you’re adding text input fields to those view controllers pushed on modal navigation controller, for iOS8, keyboard presentation and dismissal will automatically resize them to the wrong size. Unfortunately I still don’t have proper fix for this issue.

Switch view when press button

I want to change view when I press a button.
in the root view .h i have this:
#interface MainViewController : UIViewController
-(IBAction)switchToMap;
#end
and in the .m I have this:
-(IBAction)switchToMap
{
CustomViewController *customViewController = [[CustomViewController alloc] initWithNibName:#"CustomViewController" bundle:nil];
customViewController.title = #"Mappa";
[self.navigationController pushViewController:customViewController animated:YES];
//[self.view addSubview:customViewController.view];
}
the code doesn't work, but if I use the second method [self.view addSubview:customViewController.view];works, and I don't know why.
This is because you don't have UINavigationController as your rootViewController.
AppDelegate.m
UINavigationController *navigation=[[UINavigationController alloc] initWithRootViewController:mainVC];
self.window.rootViewController=navigation;
try doing this:
ViewController *CustomViewController = [[ViewController alloc] init];
[self presentViewController:CustomViewController animated:YES completion:nil];

iOS 6: supportedInterfaceOrientations is called but shouldAutorotate is not called

I know this question has been asked before here iOS 6 shouldAutorotate: is NOT being called. But my scenario is a bit different.
Initially, on application launch I load a viewController like
self.window.rootViewController = self.viewController;
and When this view is loaded I am using a custom tabBar view (inherited from UIView) which has 5 UINavigationController for each tab. The code of this viewController Class is:
\\\ .h File
#protocol tabbarDelegate <NSObject>
-(void)touchBtnAtIndex:(NSInteger)index;
#end
#class tabbarView;
#interface ViewController : UIViewController <tabbarDelegate>
#property(nonatomic,strong) tabbarView *tabbar;
#property(nonatomic,strong) NSArray *arrayViewcontrollers;
#property(nonatomic,strong) UINavigationController * navigation1;
#property(nonatomic,strong) UINavigationController * navigation2;
#property(nonatomic,strong) UINavigationController * navigation3;
#property(nonatomic,strong) UINavigationController * navigation4;
#property(nonatomic,strong) UINavigationController * navigation5;
#end
and m file is
- (void)viewDidLoad
{
[super viewDidLoad];
CGFloat orginHeight = self.view.frame.size.height- 60;
_tabbar = [[tabbarView alloc]initWithFrame:CGRectMake(0, orginHeight, 320, 60)];
_tabbar.delegate = self;
[self.view addSubview:_tabbar];
_arrayViewcontrollers = [self getViewcontrollers];
[self touchBtnAtIndex:0];
}
-(void)touchBtnAtIndex:(NSInteger)index \\This delegate method is called on every custom tabBar button clicked.
{
UIView* currentView = [self.view viewWithTag:SELECTED_VIEW_CONTROLLER_TAG];
[currentView removeFromSuperview];
UINavigationController *viewController = [_arrayViewcontrollers objectAtIndex:index];
viewController.view.tag = SELECTED_VIEW_CONTROLLER_TAG;
viewController.view.frame = CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height- 50);
[self.view insertSubview:viewController.view belowSubview:_tabbar];
}
-(NSArray *)getViewcontrollers
{
FirstViewController *firstController = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondController = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
ThirdViewController *thirdController = [[ThirdViewController alloc]initWithNibName:#"ThirdViewController" bundle:nil];
ForthViewController *forthController = [[ForthViewController alloc]initWithNibName:#"ForthViewController" bundle:nil];
FifthViewController *fifthController = [[FifthViewController alloc]initWithNibName:#"FifthViewController" bundle:nil];
navigation1 = [[UINavigationController alloc] initWithRootViewController:firstController];
navigation2 = [[UINavigationController alloc] initWithRootViewController:secondController];
navigation3 = [[UINavigationController alloc] initWithRootViewController:thirdController];
navigation4 = [[UINavigationController alloc] initWithRootViewController:forthController];
navigation5 = [[UINavigationController alloc] initWithRootViewController:fifthController];
NSArray* tabBarItems = [[NSArray alloc] initWithObjects:navigation1,navigation2,navigation3,navigation4,navigation5, nil];
return tabBarItems;
}
I have also implemented UINavigationController's category for rotation as:
#implementation UINavigationController (autoRotation)
-(BOOL)shouldAutorotate {
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations {
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
My Problem is that only supportedInterfaceOrientations method is called and shouldAutorotate is never called. The main Window's rootViewController is ViewController class, not any UINavigationController or UITabBarController. What I am doing wrong? Please help me.
If you add these to your root view controller:
- (BOOL)shouldAutorotate
{
NSLog(#"ViewController shouldAutorotate super=%d", [super shouldAutorotate]);
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSLog(#"ViewController supportedInterfaceOrientations");
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
you will see that the system is constantly sending both of these messages. Your code there can query the active Navigation Controller to see what values to return if you wish.
Also, I'm no fan of using a category to override these on a UINavigation Controller - that it works is somewhat of a fluke and importing some other library that does the same could cause unexpected consequences later on. Just create a really simple subclass and over ride both of these. I've been doing that with both UITabBarController and UINavigationController since iOS4 and never had an issue.

UINavigationController based app with FlipSideView with another UINavigationController

I'm trying to develop an app (game) with this architecture:
Main view is a naviagtioncontroller based with navbar hidden
in Main view I need a light info
button to show a options/credits
flipsideview
this flipsideview must have another
navigationcotroller with a right bar
button to a "Done" system button
The problem is that the flipsideview doesn't show the done button and it seems to show the Main navigation controller...
This is the code.
AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Main View (loaded from a XIB). Extract only of showInfo:
-(IBAction) showInfo:(id)sender {
FlipSideViewController *controller = [[FlipSideViewController alloc] initWithNibName:#"FlipSideView" bundle:nil];
controller.delegate = self;
controller.title = #"Info";
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleDone
target:controller action:#selector(done:)];
navController.navigationItem.rightBarButtonItem = doneButton;
controller.navController = navController;
[self presentModalViewController:navController animated:YES];
[doneButton release];
[controller release];
[navController release];
}
- (void)flipsideViewControllerDidFinish:(FlipSideViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
FlipSideView. In the XIB I've only a blank view with outlet linked to the UIViewController view.
#protocol FlipsideViewControllerDelegate;
#interface FlipSideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
UINavigationController *navController;
}
#property (nonatomic,assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic,retain) UINavigationController *navController;
-(IBAction)done;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipSideViewController *)controller;
#end
}
Implementation file...
- (void)viewDidLoad
{
[super viewDidLoad];
self.navController.navigationItem.title = #"Pippo";
}
#pragma mark - User Methods
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish:self];
}
The result is:
Main View showing without navigation
bar
Click on info button
Flipsideview showing with animation
and navigation bar with title "Info" and not "pippo
and not "Done" button on the right...
Where am I wrong??
Don't you get two navigationBar with navigationItems on FlipsideViewController? I am fighting with this bug now.

Resources