UITabBarController initializes with nothing selected - iphone

I've got a UITabBarController in my project that I'm creating programmatically - without a nib. I create the view controllers, initialize them, and then create an array of them and use the setViewControllers:animated: method on my tab bar controller. This works except that when it appears, my tab bar controller doesn't have anything selected. If I call [ tabBarController setSelectedIndex:1 ], then it works just fine, but if I call [ tabBarController setSelectedIndex:0 ], nothing is selected. Is this a weird bug or am I doing it wrong? This is using the iPhone SDK 3.0.

Show your code if you will, will make it easier for us to find the problem...But from not seeing anything, what I would think is wrong is that when you initialize your UITabBarButtons you are not giving any of them an index of 0...

It turns out that the code was written by me a long time ago, when I did stupid things like override the -tabBarItem accessor method in the UIViewController. Moving the tab bar item customization to -initWithStyle: fixed this problem.

This happened for me when I set the UIViewController's tabBarItem property in viewDidLoad instead of its init method.

Related

popViewController / viewWillAppear not animated in iOS 5

I wasn't lucky with searching for this, so here we go ;)
I have a UIViewController with a custom UINavigationBar which pushes another UIViewController as subview.
Everything works fine except when I click the back button on the subview. The previews (first) view appears correctly, but not animated. The animation of the UINavigationBar is correct, only the views switch immediately.
The function - (void)viewWillAppear:(BOOL)animated of the first UIViewController gets called with NO for animated. This only happens when I test with iOS 5, not with iOS 4.
Does anyone know how to fix this?
Thanks for your help! Hannes
UPDATE 1
I just removed all custom code and just used the plain UINavigationBar (so no extra settings) and it still doesn't work with iOS 5. This is my code I use in the first ViewController to push the second ViewController:
[self.navigationController pushViewController:secondViewController animated:YES];
As I already mentioned - when I click the back button in the navigation bar on the second view the first view appears immediately without animation.
Any help would be appreciated! Thanks!
UPDATE 2
I feel like I'm getting closer to the issue, but still no solution:
I just added a custom UINavigationController where I just call [super popViewControllerAnimated:animated]. This get's called correctly (animated is YES) but the viewWillAppear of the first UIViewController gets NO as value for animated...
I was having a similar problem today where the UIViewController was getting NO in viewWillAppear, except with the standard UINavigationBar and UINavigationController.
It turned out to be due to manually calling viewWillAppear:YES somewhere it shouldn't have been. This item suggests that it can also be caused by calling the wrong super method somewhere (e.g. [super viewWillAppear:animated] instead of [super viewDidAppear:animated] inside of viewDidAppear).
As for using a custom UINavigationBar, I ran across this link today that may help your case: http://sloshire1.posterous.com/simple-fix-for-viewwillappear-in-ios5
Apple implemented official ways to create custom navigation bars in iOS 5. Unfortunately, they also broke most of the non-official ways of doing it in iOS 4. iOS 5 won't call drawRect for you anymore. You need to have two ways of doing it, one for iOS 5 and greater, using the new calls, and one for iOS 4 and earlier, using the old calls. Check out the documentation for custom navigation bars in iOS 5 for more info.
Did you try to remove all your custom code and go with the native navigation bar? Does the behavior stay the same? This way you can check if your custom bar messes with the transition.

how to refresh UX data on a ViewController when its TabBarItem gets tapped?

In the view controller that has a UITabBarItem, i realized that viewDidLoad() method only gets called the first time when the tab bar item is clicked. So I dont know how to bring up the dynamic graphics when it's clicked the 2nd time. Can some guru help me on this? thanks in advance.
Should I conform to some kind of delegates or should i do it within didSelectViewController method on the root controller of all the tab bars? If i do the later one, it just seems to be weird since i think the controller that has the corresponding tab bar item should render itself instead of doing the rendering on root controller..
You want to put any code that should run every time the view controller appears in viewWillAppear: instead of viewDidLoad. viewDidLoad is designed for code that should run when the view backed by your UIViewController is created (and then possibly re-created after being thrown away during low-memory situations).
Actually i resolved this by using the parameter passed into the callback didSelectViewController(param).

Tab Bar Items selected in the More... tab get the title "Item"

I have an app delegate, which is also UINavigationControllerDelegate (and I've tried setting it as UITabBarControllerDelegate and UITabBarDelegate before asking, if that would trigger something to work, but...).
In mainwindow.xib, I have a tab bar with 6 items, which become split up into 4 + a more tab, which goes to the standard view with the two remaining tabs (in a list).
This tab bar has a controller which is the root controller over the nav controller, and called rootCt.
Now, the problem is that selected the tabs in the More nav ctlr makes the selected viewcontroller's title nil, showing "Item" instead of the tab title.
I would like to get the title as set in IB, as I've made localized nibs. Ie., simply the title that you click on in the More view.
I've tried:
UITabBarItem *item=[[appd rootCt].tabBar.items objectAtIndex:4];
NSString *str=[item title];
self.title=str;
But this gives nil. Changing index to 3 gives the 3rd title correctly, and 5 results in a crash.
Tried:
NSString *str=[appd rootCt].selectedViewController.title;
This also gives nil, because it's not set yet - that's what I need to set in this code.
I can't use selectedViewController.title, as that's nil and that's what I'm trying to set. Right?
How do I get the selected tab title coming from the More view? Should it be this hard?? Or have I missed something obvious...
First of all, where are you attempting to run the code you've pasted above? We probably need more detail to help you out here.
The correct place to set the title (if you wanted to overwrite what's set in the xib, which it doesn't sound like you want to do!) is in the UIViewController that's being displayed, in its viewDidLoad or viewDidAppear methods. If you use viewWillAppear, it may not be set yet.
But it really sounds to me like your xib isn't set up correctly.
Another question for you is what template did you start with in Xcode? It's significantly harder to set all this stuff up "by hand" than it is to use the standard template.
It must have been a lost outlet reference or similar. Deleting the .xib and redoing the work solved it.

iPad : two-stage method implementation

here is my problem, I hope someone can help me.
My iPad app is made like this : I have several viewControllers added as tabs in a tabBarController added to window in my appDelegate. In each of these viewControllers I got two navigationControllers with one viewController in.
Appdelegate
TabBarController
viewController
navigationController
viewController
navigationController
viewController
viewController
navigationController
viewController
navigationController
viewController
Everything work fine in simulator but when I run it on device I got this warning :
Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.
It only happen when I run it on a device in landscape mode. The first navigationController of the default view shown by the tabBarController take all the screen width (not important here but it's to explain that this warning makes my layout going crazy). In portrait nothing is traced in the console.
I read many things about this message but I can't find any solution to make it go away.
I'm sure it's a story of shouldAutoRotate or something like this.
I also notice that if i remove the tabBarController and simply add my first viewController to window, the message is not shown.
Very strange... please help :)
I think you should rely on the standard UISplitViewController available under iPad. This controller is what is used under the Settings app and various other apps.
If you do not feel comfortable with such a tool, you can take a look at the APSplitViewController plugin developed by slatvick on GitHub. This could solve a lot of your problems, I hope.
Edit
Googling about this issue, I found out that this warning appears when you create a wrong hierarchy of view controllers. In this case, you are pushing two navigation controllers inside a view controller, even if a view controller is not meant to contain different navigation controller. Probably there could be a problem related on how you send up to the parent view controller methods like viewDidLoad or viewWillLoad: etc. You should try to understand if you are passing all these call correctly to the parent view controller from the inner navigation controllers.

UITabBarController and selectedIndex

didSelectViewController is not being fired when selectedIndex is set programmatically on UITabBarController object, when tapping manually everything works fine.
From my current work, it seems selectedIndex is updated only if the tabbed view hasn't been loaded before - perhaps the same applies to the responder chain "the other way around".
You might have more luck by switching tabs using selectedItem, at least I can identify the correct tab in the viewWillAppear in a tab's viewcontroller using the Item, but not the Index.
For you, the most obvious "fix" would be to also invoke didSelectViewController in every piece of code that changes the Index.