I have one problem. in my app (it is tabbed style), I have one viewcontroller with some text and second with table view (RSS reader). When I have just the RSS and it is set to single view app, subview form rss works, but when I set up the tabbed app and click to some post in table view, subview didnt show up... Can anybody help me please?
Here are my codes:
AppDelegate.h
#import <UIKit/UIKit.h>
#interface MWFeedParserAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#end
AppDelegate.m
#import "MWFeedParserAppDelegate.h"
#import "ViewController1.h"
#import "RootViewController.h"
#implementation MWFeedParserAppDelegate
#synthesize window;
#synthesize navigationController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch
UITabBarController *tbc = [[UITabBarController alloc]init];
ViewController1 *vc1 = [[ViewController1 alloc]init];
RootViewController *vc2 = [[RootViewController alloc]init];
[vc1.tabBarItem setTitle:#"Tab1"];
[vc2.tabBarItem setTitle:#"Tab2"];
[tbc setViewControllers:[NSArray arrayWithObjects:vc1, vc2, nil]];
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
[window setRootViewController:tbc];
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Save data if appropriate
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[navigationController release];
[window release];
[super dealloc];
}
#end
From the dealloc, I see you are not using arc.
You have some memory leaks; be sure to release vc1 and vc2 in your didFinishLaunchingWithOptions, the tab bar controller will retain them.
You probably don't need navigationController property, recommend you delete that until you know you'll need it.
I think you'll want to add your RSS view (vc2?) to a nav controller before adding to the tab bar controller like this:
[tbc setViewControllers:[NSArray arrayWithObjects:vc1, [[[UINavigationController alloc] initWithRootViewController:vc2] autorelease], nil]];
And delete this line:
[window addSubview:[navigationController view]];
Best of luck!!
edit Spelled out a tad more:
ViewController1 *vc1 = [[[ViewController1 alloc] init] autorelease];
RootViewController *vc2 = [[[RootViewController alloc] init] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:vc2] autorelease];
UITabBarController *tbc = [[[UITabBarController alloc] init] autorelease];
[tbc setViewControllers:#[vc1, navController]];
[window makeKeyAndVisible];
[window setRootViewController:tbc];
Related
I want to change view by clicking button with NavigationController
So I added a button to Main.storyboard and write some codes like
#property (weak, nonatomic) IBOutlet UIButton *button;
in my ViewController.m (Created automatically when I made my project)
And I added method
- (IBAction)buttonClicked:(id)sender {
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondViewController animated:YES];
}
(I made SecondViewController.m, SecondViewController.h, SecondViewController.xib)
After this, I started the application and clicked the button but the screen didn't change.
Actually, when I added log like
NSLog(#"%#", self.navigationController);
null was printed.
I think I need to add some code about NavigationController to AppDelegate.m but I don't know what to do. Please help me.
Try This,
in Appdelegate.m
`- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController"
bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}`
You need to embed Navigation Controller through code or Storyboard.
First select your initial viewcontroller in storyboard and embed it in NavigationController.
Then give a storyboard identifier to the second viewcontroller.
Then lastly instantiate Second ViewController from storyboard and push it.
- (IBAction)buttonClicked:(id)sender {
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:entryController animated:YES];
}
I have the following view controllers stack.
First, my app will show an app tour page. (Say TourViewController - super class is UIViewController). Added this controller in AppDelegate as rootviewcontroller.
self.window.rootViewController = tourViewController;
Then from the tour page, if the user taps on "Signin" button, I'm presenting the second view controller (Say LoginViewController - super class is UIViewController).
UINavigationController *loginNavigationController = [[UINavigationController alloc] initWithRootViewController:self.loginViewController];
[self presentViewController:loginNavigationController animated:YES completion:nil];
After a successful login, I need to resign the second view controller (LoginViewController) and want to show a tab bar based view for further needs.
I tried this code inside the login success method.
[self dismissViewControllerAnimated:YES completion:^{
TabBarViewController *tabController = [[TabBarViewController alloc] init];
[self presentViewController:tabController animated:NO completion:nil];
AppDelegate *applicationDelegate = [[UIApplication sharedApplication] delegate];
applicationDelegate.window.rootViewController = tabController;
}];
Problems:
When I'm in the LoginViewController, I have two view controllers in my stack. So even I resign the LoginViewController, the another one (TourViewController) remains in the screen.
If I tried the above code, tab bat controller was successfully added as root view controller. But, when the LoginViewController resigns, the background was filled by TourViewController
What I need is, When I resign the LoginViewController, the background view should be tab bar controller instead of TourViewController.
Help needed!!
u can change the root view controller in AppDelegate not in the success method of the loginNavigationController better u can do this way
in AppDelegate.h
#import <UIKit/UIKit.h>
#import "TabControllerViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
- (void)showTabController; //add this method call from on success method of log in completion
#end
in AppDelegate.m
- (void)showTabController;
{
TabControllerViewController *tabController = [[TabControllerViewController alloc] initWithNibName:#"TabControllerViewController" bundle:nil];
self.window.rootViewController = tabController;
[self.window makeKeyAndVisible];
}
and in loginNavigationController.m
[self dismissViewControllerAnimated:YES completion:^{
//TabBarViewController *tabController = [[TabBarViewController alloc] init];
// [self presentViewController:tabController animated:NO completion:nil]; //no nee to present
AppDelegate *applicationDelegate = [[UIApplication sharedApplication] delegate];
[applicationDelegate showTabController]; //there is no need to create a tab bar in loginview controller, create it in root view controller
//applicationDelegate.window.rootViewController = tabController;
}];
NOTE: above is not tested just try it once
Edit 1
one way u can do it but with different animation,
form this answer u can change to second window by doing some animation for example
in in AppDelegate.h
#import <UIKit/UIKit.h>
#import "TabViewController.h"
#import "LoginViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window; //holds initial window, holds tour and login controller
#property (strong, nonatomic) UIWindow *tabWindow; //holds only tab controller
//..other code below is my test
#property (strong, nonatomic) TabViewController *tabViewController;
#property (strong, nonatomic) LoginViewController *loginController;
- (void)showTabController;
#end
in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_tabWindow = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
_window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
// Override point for customization after application launch.
_loginController = [[LoginViewController alloc]initWithNibName:#"LoginViewController" bundle:nil];
_tabViewController = [[TabViewController alloc] initWithNibName:#"TabViewController" bundle:nil];
self.window.rootViewController = _loginController; //for test for your case it contains tour view controller
[self.window makeKeyAndVisible];
return YES;
}
- (void)showTabController;
{
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
self.window.rootViewController = _tabViewController;
} completion:^(BOOL finished) {
// [_tabWindow makeKeyAndVisible];
}];
}
Do one thing,
Create UINavigationController in AppDelegate.h so you can access it anywhere.
Logic
Whenever you need to change navigation controller you must have to put your Controller to Navigation stack.
So first of all you have to create ViewController/ Tabbarcontroller object and assign it to navigationController and then show the navigationController.
AppDelegate* myDelegate = (((AppDelegate*) [UIApplication sharedApplication].delegate));
InitialViewController *initialVC = [self.storyboard instantiateViewControllerWithIdentifier:#“InitialVC"];
myDelegate.navController = [[UINavigationController alloc] initWithRootViewController:initialVC];
myDelegate.window.rootViewController = myDelegate.navController;
[myDelegate.window makeKeyAndVisible];
I'm creating an application that has 2 main view controllers at the moment. The app loads into the initial viewController, and clicking a button inside should bring up the second viewController. Here's what I have:
AppDelegate.h
#import <UIKit/UIKit.h>
#import "ViewController1.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController1 *mainViewCtr;
#property (strong, nonatomic) UINavigationController *navigationController;
#end
AppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {
_mainViewCtr = [[ViewController1 alloc] initWithNibName:#"mainViewCtr" bundle:nil];
_navigationController = [[UINavigationController alloc] initWithRootViewController:_mainViewCtr];
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.rootViewController = _navigationController;
_navigationController.delegate = self;
_navigationController.navigationBarHidden = YES;
[_window addSubview:_navigationController.view];
[self.window makeKeyAndVisible];
}
and my button method inside viewcontroller1:
- (IBAction)SessionNickNameSubmit:(id)sender {
ViewController2 *secondViewCtrl = [[ViewController2 alloc] initWithNibName:#"secondViewCtrl" bundle:nil];
[self.navigationController pushViewController:secondViewCtrl animated:YES];
}
but when I click the button the view doesn't change. I tried debugging and the code is hit, but nothing happens.
am I missing a setting somewhere?
UPDATE
I've updated all viewController variable names:
instead of ViewController1/2 I'm using mainViewCtrl and secondViewCtrl
but still no use :(
You made a typo:
it's
_window.rootViewController = _navigationController;
not
_window.rootViewController = _joinViewController;
And NeverHopeless's suggestion is also spot on. It's probably the typo AND the fact that you add your second viewcontroller as ViewController2 and not using a proper variable name.
Another suggestion is making a storyboard (if you are not using one) and adding a segue for the transition. Simply assign the segue processing to the button. Like this:
-(IBAction)SessionNicknameSubmit:(id)sender
{
[self performSegueWithIdentifier:#"identifier" sender:self ];
}
Here is a nice description of how it works and how to use it plus some useful pointers!
Obj-C is a case sensitive language, class name and instance name should not be the same like ViewController2. Try like this:
- (IBAction)SessionNickNameSubmit:(id)sender {
ViewController2 *viewController2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
[self.navigationController pushViewController:viewController2 animated:YES];
}
The reason is that you have set the window's rootViewController to ViewController1.
You need to set you navigation controller to the window's rootViewController.
So that when you try to access the self.navigationController on the press of the button, it will access the navigation controller in which the self resides i.e. your window's rootViewController now.
Then it will push the next view controller properly.
After looking at almost every tutorial and every stack overflow answer, I finally found a solution that worked. I had to make an instance of the storyboard in the app delegate and use that to create my first view controller instance.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.joinViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:joinViewController];
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
navigationController.navigationBarHidden = YES;
_window.rootViewController = navigationController;
[_window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
I think the problem was that when I was creating an instance of ViewController, it was creating a new instance and binding the navigation controller to it (independent of the view controller that was showing up in the simulator). So when I was using the push method it wasn't recognizing self.NavigationController (that's why NSLog(self.NavigationController == nil) was logging 1
thank you for taking time to answer me !
I'm inexperienced in IOS development, after several searches on google, I turn to you.
My problem is that : I will wish to use UINavigationController, with new main view, to allow me to create a back button.
Here is my AppDelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
MainViewController *mvc = [[MainViewController alloc]init];
//self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
//UINavigationController * navController = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = mvc;
[self.window makeKeyAndVisible];
return YES;
}
and my AppDelegate.h :
#class ViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
//#property (strong, nonatomic) ViewController *viewController;
#end
During development I changed the main view of the application as you can see above the two lines commented out.
I would like to use "UINavigationController" with this new main view, what does it change? and where?
Thank you and sorry if i'm not clear ! (Google Translate)
Set your MainViewController *mvc as the root of your navController and make it the root view controller of the window.
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController: mvc];
self.window.rootViewController = navController;
I am creating a class object from my UIViewController and trying to push a controller from it, and it won't work.
I have been doing research but found nothing, any idea?
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.newClass = [[MyNewClass alloc] init];
self.newClass.view = self.view;
self.newClass.navigationController = self.navigationController;
[self.newClass connect];
}
...
#end
MyNewClass.h
#interface MyNewClass : NSObject<UINavigationControllerDelegate>
#property(nonatomic, retain) UIView *view;
#property(nonatomic, retain) UINavigationController *navigationController;
-(void) connect;
#end
MyNewClass.m
-(void)connect
{
OtherViewController * otherVC =
[[OtherViewController alloc] init];
self.navigationController pushViewController:otherVC animated:YES];
}
...
add folloeing code into appdelegate's didFinishLaunchingWithOptions method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self copyDatabaseIfNeeded];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window makeKeyAndVisible];
return YES;
}
and then remove all other UINavigationController declaration and allocation. Like MyNewClass's NavigationVontroller. Because here you declare and allocate navigationcontroller in appdelegate so you can use it in whole app.
When viewDidLoad is called, the view has just been loaded but the view controller hasn't necessarily been added to a navigation controller yet. So using viewDidLoad as your trigger is not useful.
A better approach is to explicitly pass the navigation controller to the view controller when it's created. Or to implement didMoveToParentViewController: and do your configuration there.
You are pushing a viewController from a controller, which is not a part of navigationController, so first make it part of navigationController, then try