I'm developing a menu for a game. The menu contains four buttons; Campaign, Training, Highscore and Settings.
When I click one of these buttons, a new view controller should be shown. I add the new view controller using this function:
[self.view addSubview:myViewController.view];
It does show the new view controller, but I can still touch the menu buttons from the other view controller that is "behind" the new. I can't see the buttons, but when I touch in the area of a button, the button's IBAction is called.
Of course, I can disable all buttons before adding the subview, but is this the right way to fix it? Should I remove the menu from its subview? I'm using a window-based application and do not have a tab bar or a navigation bar.
Thank you very much!
You could use a modal view:
[self presentModalViewController:myViewController animated:YES];
I think that would be the right way to do this.
You need to remove the old view from the screen when you add the new one. Three ways to do this, from my most preferred to least preferred:
Use a navigation controller and just turn off the navigation bar (by setting self.navigationController.navigationBarHidden to YES).
Use presentModalViewController:animated:, as subw recommends.
Do the following instead of what you're doing currently:
[self.view.window addSubview:myViewController.view];
[self.view removeFromSuperview];
There are two main differences between the three approaches.
One is the animation involved. #1 slides the new screen in from the right. #2 slides it up from the bottom (or cross-dissolves or flips, depending on your preference). #3 does not have any animation by default.
The other is how you go back to the menu. In #1, any part of your code (more or less) can call ([self.navigationController popViewControllerAnimated:YES]. In #2, the child view controller calls [self.parentController dismissModalViewControllerAnimated:YES]. #3 has no simple way to go back; you have to do it manually, which involves keeping a reference to the menu view controller in each of the other view controllers.
The only problem with what you're doing now is that the touches are getting passed along rather than handled by your new view. I would go one level above the menu, remove the menu and add the new view. If you need the menu back, do the opposite. I tend to use presentModalViewController for short things, like preferences, but for the full game I'd unload the menu. It's your call though.
Related
I'm new to iPhone development (except developing with cocos2d).
I want to create a simple application that have one window with a button. When i press the button i want some other window to be shown.
Where can i read how do such things?
Also i don't understand well what is View, ViewController, Window. I've read the your first iOS app example.
Look for tutorials on UINavigationController, like this one.
For the meaning of view and view controller you certainly want to read the apple references or in wikipedia. The topic there would be MVC Pattern.
As to your concrete problem:
There is usually only one window in iPhone apps so you certainly want to have a button on a view and if you push that button that view disappears and instead a new view is shown.
You accomplish that by removing the view with the button from its superview ( have a look at the topic tree hierarchy ) and then add the view you want to bee shown as a subview to the main window .
Bottom line is there is one main window and you put views onto it by it's addSubview method. And you remove views by calling their removeFromSuperview method
You should to read it again or google it until you'll understand it well.
view is the graphic output, while view controller is what "manage" the behavior of the view in every event.
your function to navigate -
(IBAction) ButtonClicked
{
static YourViewController *viewController=nil;
if(viewController==nil)
viewController=[[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
[self.navigationController pushViewController:viewController animated:YES];
}
I'm writing an iphone app that has 3 tabs. The first two are UITableViews, but the third tab i want to be a UINavigationController, because it is to be used for editing a list of recipes.
I've tried every combination of nibs i could think of to get this to work properly but am having problems such as:
once you click on the editing tab, then click back to the other tabs, the display still shows parts of the editing tab such as the navigation bar
when you click on the editing tab, you can see a blank navigation controller with no contents or title, even though my nav controller inside the tabs has the 'nib name' and the 'class' set in the inspector
I just would like to know the best way of going abouts doing this: putting an editor (which i think should be a navigation controller?) inside a tab. Is there something glaring i'm missing?
Thanks so much guys
I use to do editing buttons with navigation controller as well and it woks very well, so this is probably good option.
If you want navigation controller just for one view you need to hide it by switching tabs
self.navigationController.navigationBarHidden = YES; or NO
And since I don't use IB (it is black box) I would recommend you to allocate all (title, buttons, etc.) about navigation controller manually. Works great and you see what you've done.
OK i solved it. I was on the right track already anyway.
My main window now has a tab bar controller. One of the tabs has its nib name and class set to my view with navigation.
In my view with navigation, in the nib i have an empty view and a navigation controller. In the implementation file, i have the following code to attach the nav controller into the empty view, and it works nicely now!
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview:navController.view]; // This is the important line
}
Ok, this is an odd one and I can reproduce it with a new project easily.
Here is the setup:
I have a UISplitViewController. In the left side I have a UITabBarController. In this tab bar controller I have two UINavigationControllers. In the navigation controllers I have UITableViewControllers. These table views have search bars on them.
Ok, what happens with this setup is that if I'm in portrait mode and bring up this view in the popover and I start a search in one of the table views and cancel it, the navigation bar becomes unresponsive. That is, the "back" button as well as the right side button cannot be clicked.
If I do the exact same thing in landscape mode so we are not in a popover, this doesn't happen. The navigation bar stays responsive.
So, the problem only seems to happen inside a popover.
I've also noticed that if I do the search but click on an item in the search results which ends up loading something into the "detail view" of the split view and dismissing the popover, and then come back to the popover and then click the Cancel button for the search, the navigation bar is responsive.
My application is a universal app and uses the same tab bar controller in the iPhone interface and it works there without this issue.
As I mentioned above, I can easily reproduce this with a new project. Here are the steps if you want to try it out yourself:
start new project - split view
create new UITableViewController class (i named TableViewController)
uncomment out the viewDidLoad method as well as the rightBarButtonItem line in viewDidLoad (so we will have an Edit button in the navigation bar)
enter any values you want to return from numberOfSectioinsInTableView and numberOfRowsInSection methods
open MainWindow.xib and do the following:
please note that you will need to be viewing the xib in the middle "view mode" so you can expand the contents of the items
drag a Tab Bar Controller into the xib to replace the Navigation Controller item
drag a Navigation Controller into the xib as another item under the Tab Bar Controller
delete the other two view controllers that are under the Tab Bar Controller (so, now our tab bar has just the one navigation controller on it)
inside the navigation controller, drag in a Table View Controller and use it to replace the View Controller (Root View Controller)
change the class of the new Table View Controller to the class created above (TableViewController for me)
double-click on the Table View under the new Table View Controller to open it up (will be displayed in the tab bar inside the split view controller)
drag a "Search Bar and Search Display" onto the table view
save the xib
run the project in simulator
while in portrait mode, click on the Root List button to bring up popover
notice the Edit button is clickable
click in the Search box - we go into search mode
click the Cancel button to exit search mode
notice the Edit button no longer works
So, can anyone help me figure out why this is happening?
Thanks,
Mark
Ok, got an answer from Apple Developer Technical Support. They investigated it and found it is a bug in the UIPopoverController. He gave me a workaround that kind of works but the right button in the nav bar ends up sliding across the screen after canceling the search. But, at least it fixes the issue. He also suggested I send in a bug report to Apple and I've done that as well. Hopefully they will fix this in the next version of the SDK.
Here's a copy of the relevant portion of the Apple engineer's response:
I've created my own project and dipped into what is going on and it looks like it's a bug in the UIPopoverController where after the UISearchBar is being dismissed, something is being obstructed in the navigation bar.
There's a workaround that I've found for now, though the animation that occurs is not amazingly optimal:
- Use the – searchBarCancelButtonClicked: method of UISearchBarDelegate and add the following:
self.navigationItem.rightBarButtonItem = nil;
self.navigationItem.rightBarButtonItem = self.editButtonItem;
As I said, it looks like the popover is pushing the button onto the navigation bar, so it may not be what you're looking for.
I tried the rightBarItem technique mentioned, but it didn't work for me. I had to do this (which is also a hack really)
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self.navigationController setNavigationBarHidden:NO animated:NO];
This might be because my UINavigationBar isn't one unified with the popover, but I can't say for sure.
I have a tab bar view, and another UIView which contains a button, which needs to be visible just above the tab bar.
I have added another view which always sits above the current select tab's view, but can't figure out how to make it sit just above the tab bar Screenshot http://img.skitch.com/20090524-jq6ufyiwp6c2uu1x5tkrrsd97m.jpg
I would suggest sub-classing the tabbar to include the new view. That way you do not have to worry about a tab overlaying the view. All your resizing should be done automatically and you will never accidentally hide a component.
You can also have the controller also look after the button and view that you add. you would just need to replace the tabbar in the tabbarviewcontroller to be your one.
Add your view with button in the tab bar view and use either one of these
– bringSubviewToFront:
– insertSubview:aboveSubview:
to put it above all and check how many pixels you need to position your button so that it does not get above the tabs.
You could also add it at the window level.
I have been in the process of learning to build iPhone applications for the last two weeks. I've gotten through a fair amount of content, and now I'm trying to create a modal pop up with presentModalView.
I can can successfully create and slide up a view, but I notice that modal views don't provide you with a default navigation bar at the top of the window, which makes sense for flexibility I guess. Most modal views I've seen have a "Cancel" and a "Done" or "Save" button as navigationItems on what looks to be a UINavigationController. My thought then was just to instantiate a navigation controller and push the single view onto the view controller stack, and presentModalView:navController.view ...
Because the view is relatively complex, I was trying to lay out both the UINavigationController, with the bar buttons, and the view I was hoping to push onto the stack in a single xib -- no matter what I try, I can't seem to get the linkages correct. Can you even do this? Or should I create a separate class/xib for the view I'm going to be pushing onto the navigation controller? Seems like a lot of classes and files for one screen, so my feeling is I must be missing something.
At this point, I could have done it programmatically about an hour and a half ago... however, this is a real nag, since IB seems GREAT for some things. Anyone have an experience with a situation like this?
Thanks,
Josh
If you're not going to use this new XIB for navigation, there's no point in making a navigation controller.
In interface builder, simply drag a UINavigationBar to the top of your view, and add a "Done" Button. Now, add an IBAction to the done button to dismiss the view controller. Your ViewController code for the dismiss IBAction should look something like this:
-(IBAction)dismiss {
//Any logic before dismissing the modal view
[super dismissModalViewControllerAnimated:YES];
}