As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I have this code that works great, but out of curiosity how can I replace the word self in this method?This is a navigation app btw, and been trying all sorts of methods to replace it.
Viewcontroller1
[self.navigationController popViewControllerAnimated:YES];
Here is one method I tried,
UIViewController *vc;
vc = [[Viewcontroller1 alloc] initWithNibName:nil bundle:nil];
[vc.navigationController popViewControllerAnimated:YES];
It is not possible to replace self. Because self is a keyword like this keyword in JAVA.
IN SHORT Apple/iOS Does not provede any types of Feature That any people can change it.
**EDIT**
From Your Code :
UIViewController *vc;
vc = [[Viewcontroller1 alloc] initWithNibName:nil bundle:nil];
[vc.navigationController popViewControllerAnimated:YES];
The best way for create object of Viewcontroller1 and navigate to another viewController for write as
Viewcontroller1 *objVC = [[Viewcontroller1 alloc] init];
[self.navigationController pushViewController: objVC animated:YES];
You are wrongly interpreting below line of code.
[self.navigationController popViewControllerAnimated:YES];
This line basicaly what does . it does remove from the viewController form current NavigationViewControlelr's (i.e self.navitionController )Stack
stack-- basically when you create any viewController and that view Controller into the navigationController, then navigation controller add that viewController according to the Stack or can say manage the ViewController in stack's Way.
And About the your below line of code
UIViewController *vc;
vc = [[Viewcontroller1 alloc] initWithNibName:nil bundle:nil];
[vc.navigationController popViewControllerAnimated:YES];
Why u are creating ViewController removing form the navigationViewController. it'll craete memory overhead
and About replacing the self. you can't replace self as `iPatel' told above.
When you say you want to replace self with "an object or something", self is an object. The word self refers to the current instance of the class that the function is in. You cannot replace self because then you would not be referencing the current instance of your UIViewController subclass.
Why your example does not work:
UIViewController *vc;
vc = [[Viewcontroller1 alloc] initWithNibName:nil bundle:nil];
[vc.navigationController popViewControllerAnimated:YES];
Is because it is referencing a new instance of the Viewcontroller1 class. The popover will not appear because you are not adding it to your current viewcontroller; you are adding it to another instance that is never displayed.
Related
I have TabBar based iPhone application, and in app delegate 2 default view controllers are initialized by apple (if you choose tabbar base app when creating application).
UIViewController *rootViewController = [[tabBarBetFirstViewController alloc] initWithNibName:#"tabBarBetFirstViewController" bundle:nil];
UIViewController *accountViewController = [[tabBarBetSecondViewController alloc] initWithNibName:#"tabBarBetSecondViewController" bundle:nil];
Why this isn't initialized like this:
tabBarBetFirstViewController *rootViewController = [[tabBarBetFirstViewController alloc] initWithNibName:#"tabBarBetFirstViewController" bundle:nil];
tabBarBetSecondViewController *accountViewController = [[tabBarBetSecondViewController alloc] initWithNibName:#"tabBarBetSecondViewController" bundle:nil];
???
Is that the same ? Or it's just those default that are added by apple? If i want to add one more tab will I write:
UIViewController *third = [ThirdViewController alloc].....];
or
ThirdViewController *third = [ThirdViewController alloc]....];
Of course at the end I have:
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:rootViewController, accountViewController, third, nil];
ThirdViewController is a subclass of UIViewController, so you can write both. But if you later want to use the variable third to invoke methods that are specific to ThirdViewController, then you should use
ThirdViewController *third = [ThirdViewController alloc]....];
Summing it up: In this simple scenario there is no single right way of "doing it". The important lesson to take from this question (if it wasn't clear already) is to understand why you can assign a ThirdViewController instance to a UIViewController variable (because of the subclassing relationship).
You use the
ThirdViewController *third = [ThirdViewController alloc]....];
approach. Don't know why Apple uses the other approach. I this easy example it doesn't make any difference. But when you have properties you want to set it's better to use the class name.
It depends, if you have a view controller that you want to have a custom interface, you will want it to be a subclass of UIViewController. If ThirdViewController is a subclass of UIViewController then that code that you stated here:
ThirdViewController *third = [ThirdViewController alloc]....];
Would produce the desired result. Apple's approach is just for a generic View Controller without any properties, so ideally you would want all of your tabs to be UIViewController subclasses.
1) If you want to make use of any instance methods or properties in your ThirdViewController, then you must use
ThirdViewController *third = [ThirdViewController alloc]....];
2) If you dont have a need to do so, you can use
UIViewController *third = [ThirdViewController alloc]....]; // it'd make no difference
To be on a safer side, imo, first case is a good practice.
In this case I do not see any difference, I would prefer doing it your way. But in a situation similar to the one below, Apple's way seems better:
UIViewController *vc;
if ( some_case ){
vc = [YourViewController1 alloc]// ...;
[ (YourViewController1 *) vc doSomeThing]; // You might need to use casting for instance messages
//...
}
else {
vc = [YourViewController2 alloc]//...;
}
[self.navigationController pushViewController:vc animated:YES];
[vc release];
So I want a RootViewController that can handle a different view controller for each cell (Okay, I have my reasons not to reuse nibs here).
I can list them all up in the didSelectRowAtIndexPath like this:
if(condition){
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController"
bundle:[NSBundle mainBundle]];
dvController.selectedCountry = selectedCountry;
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
}
else if (condition2){
DetailViewController2 *dvController2 = [[DetailViewController2 alloc] initWithNibName:#"DetailViewController2"
bundle:[NSBundle mainBundle]];
dvController2.selectedCountry = selectedCountry;
[self.navigationController pushViewController:dvController2 animated:YES];
[dvController2 release];
dvController2 = nil;
}
but that can be quite long and I don't know any other way to do it. Are there some sort of "special controllers" or classes that I can use to address this? I am new to iOS development so I know just a little of it.
Thanks in advance!
I think you can use a Factory Method returning an object of UIViewController as that is the argument type of pushViewController (as you can see in the API docs for UINavigationController). Basically you create a method expecting an int,String,Enum to tell what kind of DetailView you want to create, then it creates an object of the given DetailView implementation and returns it. Then you can push that new controller using pushViewController.
I'm fairly new to Objective-C and iPhone programming so I apologize if this is a newbie question. I have a simple application that needs to go from one view, to another. The first view is a UIViewController. I set up the xib file in IB (i.e. dragged some buttons onto the window) and hooked up all the buttons (which all work). I then created another xib file and class (also a UIViewController) and hooked them up. When a button is pressed in the first view I want to load the second view. Here's the code that is supposed to be pushing the view:
-(IBAction)createAccount:(id)sender{
CreateAccountViewController*acctView = [[CreateAccountViewController alloc] initWithNibName:#"CreateAccount" bundle:nil];
[self.navigationController pushViewController:acctView animated:YES];
[acctView release];
}
But this does nothing. When I put print statements in the createAccount method those are printed (I can click the button any number of times and it never crashes) but the acctView is never pushed. When I print out the value of self.navigationController it returns null. It's even stranger because if I present the acctView modally then it works.
-(IBAction)createAccount:(id)sender{
CreateAccountViewController*acctView = [[CreateAccountViewController alloc] initWithNibName:#"CreateAccount" bundle:nil];
[self presentModalViewController:acctView animated:YES];
[acctView release];
}
This works just fine, but I don't want to use the view modally. I'm completely lost here. In the past couple of hours I've come across a lot of posts saying to do something with a UINavigationController and hook that up to my view, but how do I do that? Any help is greatly appreciated! Thanks.
It seems you haven't created a UINavigationController for your app.
Best thing would be starting from scratch with a new Xcode project, taking care of choosing a Navigation Based application. In this way you will get almost everything already set up for you.
If you don't like this approach, you can create programmatically your UINavigationController. Here you find a tutorial for doing that.
If you prefer more straight-to-the-point instructions, here they are:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
self.navigation = [[[UINavigationController alloc] initWithRootController:overviewViewController] autorelease];
[overviewViewController release];
[window addSubview:[navigation view]];
[self.window makeKeyAndVisible];
return YES;
}
whereby self.navigation is a retained property in your appDelegate.
EDIT:
This answer was quite old, therefore an update:
If you are using ARC, you should be using a strong (vs. retain) property and you would not need the autorelease;
if you target iOS > 4.0 (which is also implied by the above point), you can use the rootViewController property in UIWindow and say:
MainPageDialog *overviewViewController = [[MainPageDialog alloc] initWithNibName:#"MainPage" bundle:nil];
self.window.rootViewController = [[[UINavigationController alloc] initWithRootController:overviewViewController] autorelease];
[overviewViewController release];
[window addSubview:[self.window.rootViewController view]];
[self.window makeKeyAndVisible];
without the need for any navigation property.
I've been attempting to figure this out for a while now, but I'm up to a point where I can't seem to solve my problem from reading other Q&As. I'm trying to get the active UIViewController in a UINavigationController to send popViewController/pushViewController messages to the UINavigationController, but I cannot figure it out. I'm probably doing something rather stupid that is causing it to break. The structure should be like this, but even then I'm not sure if I've done that right.
mainController
primaryNavigationController
firstViewController
secondViewController
both firstViewController and secondViewController are a subclass
mainController.m
firstViewController = [[FirstTestViewController alloc] init];
secondViewController = [[FirstTestViewController alloc] init];
primaryNavigationController = [[UINavigationController alloc]
initWithRootViewController:firstViewController];
[primaryNavigationController.view setFrame:CGRectMake(0,0,320i,409)];
[self.view addSubview:[primaryNavigationController view]];
[primaryNavigationController.navigationBar setFrame:CGRectMake(0,0,20,44)];
primaryNavigationController.navigationBar.tintColor = [UIColor blackColor];
How can I tell primaryNavigationController to push/pop a VC from within the firstTestViewController subclass?
You would allocate the second view controller within your first view controller (because you don't need it before):
secondViewController = [[FirstTestViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
The SDK includes many sample projects that involve a navigation controller and show you how to do this.
view1 = [[View1 alloc] init]; //Create the first view
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:view1];
navigationController1.navigationBar.tintColor =[UIColor blackColor];
View1 is inherit from UIViewController. So I create a *view1, then I create a UINavigationController, call *navigationController1. How do I link the two together? Thank you very much
The way to link a view controller with a navigation controller is to push the view controller onto the navigation stack. For example:
UIViewController * yourViewController = [[UIViewController alloc] init];
UINavigationController * navigation = [[UINavigationController alloc] init];
[navigation pushViewController:yourViewController animated:NO];
[yourViewController release]
Finally release the view controller at the end since the navigation controller retains it.
You may have things a little mixed up. A UINavigationController is generally attached to a UIViewController, which itself is what contains the UIView.
Before writing your own code, you might take a look at the navigation controller sample application project that is available from Xcode's new project template list, to figure out how it works.
The answer for this question is here: Having problem with pushViewController!! Help