As stated above I'm having problems regarding UITabBarController or specifically the tab bar not responding after manually/programmatically setting the selectedViewController or selectedIndex. This also happens when I pop the view controller of the previously selected tab before moving to another tab screen. Yes I believe I have checked the multiple times the delegate for UITabBarController and yes I have confirmed that the
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
is not being fired. Is there anyone who has experienced this?
Make sure set the delegate right, if not, the delegate method won't be fired.
Seems like loading behavior of assets might have changed in iOS7
Make sure that the view is completely loaded.
Prior to iOS7, you would create the tabbed view, push it, then select the tab.
in ios7, the view is not loaded synchronously. So while you did create it and display it, the select index gets called before it is actually shown and therefore has no effect.
At least this is what bit me as we have started to transition to iOS7
Related
(Apologies for not being able to embed my images yet).
Using iOS storyboards, I have a UITabBarController with a UINavigation Controller/UITableView(1) embedded in it. This UITableView(1) then calls another UITableView(2):
What I'm trying to do is to make UITableView(2) appear when the Tab Bar is changed to that tab, and then have the UINavigationBar left arrow button exist to get back to UITableView(1).
The existing functionality I can think of which does this is the iPhone Mail app, where when you launch it you see your Inbox, and you can hit the left-arrow Mailboxes button to get back to your mail box list.
I've tried attaching the tab bar directly to UITableView(2) but it doesn't work as expected, there's no left arrow back button to get back to the previous view when the app is run.
I've also tried adding a navigation controller to that UITableView(2) and the Navigation controller correctly appears, but still without any back button:
Any suggestions as to what I'm doing wrong would be greatly appreciated, I'm fairly new with storyboards and it's difficult to find what to search to get this working.
If it's not possible with just storyboards themselves, is there some kind of automatic (non-visible) push to the 2nd UITableView I could do?
Thanks!
Nick.
This tutorial will definitely help you : http://maybelost.com/2011/10/tutorial-storyboard-in-xcode-4-2-with-navigation-controller-and-tabbar-controller-part1/
I ended up implementing it the following way, as I wanted to perform the majority of the work within storyboards.
I set up the storyboard with the tab bar embedding the UINavigationController, which contained UITableView(1) which then contained a custom segue to UITableView(2):
Then within the class associated with UITableView(1) I added this single line:
- (void)viewDidLoad {
[self performSegueWithIdentifier:#"campaigns" sender:self];
...
}
On load of the tab, the viewDidLoad of UITableView(1) instantly calls UITableView(2) without any kind of animation, showing the back button to UITableView(1), which is exactly what I wanted.
Thanks to those who responded!
You can implement the delegate method as below.
(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
In this method you can check for the tabBarController.selectedIndex or viewController object. This ensures the selection of correct tab , then push the controller having table 1, then push the controller having table 2.
So this is pretty advanced and I am not sure if it is feasible in the iOS SDK but here goes (please read carefully, I don't want skimmers preemptively answering this question before they know the details):
I have a tab bar view controller with two tabs. One tab (view controller 1) holds a data-presenting view controller, and the other (view controller 2) is a settings view. In the settings view I allow the user to specify whether they want to view a simplified or advanced version of the interface of view controller 1.
What I need to do, is based on these settings, present the chosen view for view controller 1, and I want to be able to do it on the fly (the user doesn't have to close and then reopen the app). I attempted to recreate the view controller array of the tab bar within
- (BOOL)tabBarController:(UITabBarController *)tabBarController
shouldSelectViewController:(UIViewController *)viewController
but it just caused my app to crash (SIGABRT crash), go figure...
I was thinking of making a "hollow" view controller that would be able to point to the appropriate class type but the challange I have there is making it completely transparent to any view I should choose to place in it (UITableViewController, UIViewController, etc.).
Any ideas? Thanks in advance!
Have you tried looking at the docs at all UITabBarController?
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
I'm working on an application that has a view hierarchy that is very similar to Apple's Music or iPod aps. It has a UITabBarController containing UINavigationControllers presenting UITableViews that eventually lead to a UIViewController that sets hidesBottomBarWhenPushed to YES in its designated initializer (to hide the UITabBar). The previous UITableViews all have a UISearchBar in their tableHeaderView that I move out of sight in viewWillAppear:.
The UISearch normally remains hidden until pulled down except when backing out of the UIView to a short UITableView. It remains hidden through the UITableView's viewWillAppear: and viewDidAppear: methods and the UIView's viewWillDisappear: and viewDidDisappear: methods and then finally pops down of its own accord. If I comment out self.hidesBottomBarWhenPushed = YES; in the UIView the UISearchBar stays hidden when backing out of that view.
What is causing the UITableView to reveal the UISearchBar after I have hidden it? Is there a delegate method higher up in the view hierarchy that I can use to prevent it from happening?
Update I've created a simple project with the minimum amount of code needed to reproduce the problem. Download PushySearchBar.zip. (Sorry, I had a mod_rewrite rule preventing downloads from third-party domains. I've added Stack Overflow to the whitelist. Download should work now.)
Does the UISearchBar have text in it when backing out of the UIViewController? Seems plausible that this might cause it to be displayed by default.
EDIT: (adding below comment to body of answer for easier scanning / finding, plus adding some explanation.)
Duplicate your viewWillAppear: method body in viewDidAppear: in SearchableTableViewController. This fixes the issue in my testing.
Basically, all this does is ensure that the offset is set correctly on either side of the navigation animation.
Shaun - I'm still learning Objective-C too so I might be off on this, but I think the issue is that ViewWillAppear: fires once when you get to the SearchableTableView 3 view, and then when you try to go backwards from Terminal to SearchableTableView 3 it's not firing again. I duplicated the code in ViewWillAppear: and put it in ViewDidAppear: and the search bar appears to be hiding properly.
UPDATE: This post seems to verify the above and offer cleaner solutions: iPhone viewWillAppear not firing
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.
In the iPhone, I have a tableview, and touching the cells, I have one method calling presentModalViewController, and opening another view, with email and this kind of stuff.
When the user press the cancel button, the viewWillAppear method in the previous view is called.
So far, so good. But in the iPad, the viewWillAppear is only called the first time that the view appears, anyone knows if this is a bug or it's right?
I tried to implement the
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
with no success.
Does anybody know how to fix this without doing any delegate method from scratch?
Thanks in advance
Since view controllers presented modally don't necessarily completely cover up the underlying view on iPad, the viewWillAppear method does not fire when said modal view controllers get dismissed. I rely on delegate methods to announce to the original view controller the actions of the modal view controller. I think it's the best way to go.
Based on guesswork, rather than reading, testing or anything useful really, but therefore not covered under the NDA...
Is viewWillDisappear being called when you presentModalViewController ? It may be that it doesn't think the modal view obscures the original view fully, therefore (unlike the iPhone) both exist at once ?
Chances are it's a bug, I would file a bug report with apple here.