UITabBarController turns Black while switching tabs - ios

I have embedded a UITabBarController inside a UINavigationController. The UITabBarController contains 3 different tabs which leads to 3 different UIViewControllers which displays UITableView. I implemented all these through storyboard. In the first UIViewController, I have implemented a UISearchController for the UITableView programatically which is working. The View turns black when I search for a particular cell and then if I switch tabs.
I believe that the issue has some relation to SearchController because before including the SearchController, I didn't have any issues.
I have gone through few other questions in here, but none could solve my issue.
Edited :
Below is my code related to SearchController.
#interface
#property (nonatomic, strong) UISearchController *searchController;
#property BOOL searchControllerWasActive;
#property BOOL searchControllerSearchFieldWasFirstResponder;
#implementation
viewDidAppear()
self.searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
[self.searchController.searchBar sizeToFit];
self.tblContactsTable.tableHeaderView = self.searchController.searchBar;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.definesPresentationContext = YES;
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
//reloads table view according to what is searched.
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
self.searchController.searchBar.showsCancelButton = NO;

UITabBarController should be the top most element on window from your storyboard/code and you can add the Navigation Controllers and View Controllers to UITabBarController view controllers.
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITabBarController_Class/index.html

use this sample code it will surely help you here chatlist, contactlist and findfriends are 3 UIViewControllers
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// self.navigationItem.hidesBackButton=YES;
self.navigationController.navigationBar.backgroundColor = [UIColor blueColor];
_chatlist = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ChatListVC"];
_contactlist = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ContactListVc"];
_findfriends = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"FindfriendsVC"];
self.tabbarcontroller = [[UITabBarController alloc]init];
self.viewControllers = [NSArray arrayWithObjects:_chatlist,_contactlist,_findfriends, nil];
self.tabBar.frame =CGRectMake(0,44,self.view.frame.size.width,50);
UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
UITabBarItem *item1 = [self.tabBar.items objectAtIndex:1];
UITabBarItem *item2 = [self.tabBar.items objectAtIndex:2];
item0.title = #"Chat List";
item1.title = #"Contacts";
item2.title = #"Find Friends";
[item0 setFinishedSelectedImage:[UIImage imageNamed:#"chatlist.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"chatlist.png"]];
[item1 setFinishedSelectedImage:[UIImage imageNamed:#"contacts.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"contacts.png"]];
[item2 setFinishedSelectedImage:[UIImage imageNamed:#"findfriends.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"findfriends.png"]];
}

Figured out the answer myself. I don't know if its the exact right way of doing it but now the App seems working.
I place my UITabBarController as the Initial View and separate UINavigationControllers for each tabs.

Related

IOS: Adding viewcontroller to custom TabBar in ios

i am working on a chat project in which i have to use a UITabBar. I am using storyboard in this project but according to requirement i added custom TabBar in project to mount it on the top of the view.
Now the problem is Custom TabBar is showing well on the top of view but when i click on the tabs it only shows black screen instead of showing the ViewControllers.
i am sharing my code please suggest me the solution of it.
my .h file
#interface TabBar : UITabBarController
{
}
#property(strong,nonatomic) UITabBarController *tabbarcontroller;
#property(strong,nonatomic) ChatListVC *chatlist;
#property(strong,nonatomic) ContactListVc *contactlist;
#property(strong,nonatomic) FindfriendsVC *findfriends;
#end
my .m file
#implementation TabBar
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// self.navigationItem.hidesBackButton=YES;
self.title = #"Chat Home Page";
self.navigationController.navigationBar.backgroundColor = [UIColor blueColor];
_chatlist = [ChatListVC new];
_contactlist = [ContactListVc new];
_findfriends = [FindfriendsVC new]; //initWithNibName:#"FindfriendsVC" bundle:nil];//[FindfriendsVC new];
self.tabbarcontroller = [[UITabBarController alloc]init];
self.viewControllers = [NSArray arrayWithObjects:_chatlist,_contactlist,_findfriends, nil];
//self.navigationController.navigationBar.frame.size.height;
//UITabBar *tabBar = self.tabBarController.tabBar;
//CGFloat topBarOffset = self.topLayoutGuide.length;
self.tabBar.frame =CGRectMake(0,44,self.view.frame.size.width,50);
UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
UITabBarItem *item1 = [self.tabBar.items objectAtIndex:1];
UITabBarItem *item2 = [self.tabBar.items objectAtIndex:2];
item0.title = #"Chat List";
item1.title = #"Contacts";
item2.title = #"Find Friends";
[item0 setFinishedSelectedImage:[UIImage imageNamed:#"chatlist.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"chatlist.png"]];
[item1 setFinishedSelectedImage:[UIImage imageNamed:#"contacts.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"contacts.png"]];
[item2 setFinishedSelectedImage:[UIImage imageNamed:#"findfriends.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"findfriends.png"]];
}
snapshot of the output is
It looks like your view controllers aren't being initialised properly.
If your view controllers are all in the Storyboard, try replacing
_chatlist = [ChatListVC new];
_contactlist = [ContactListVc new];
_findfriends = [FindfriendsVC new];
with:
_chatlist = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ChatListIdentifier"];
_contactlist = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ContactListIdentifier"];
_findfriends = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"FindfriendsIdentifier"];
Where the identifier string is your own identifier that you have set up in the Storyboard.

Can't push a view onto searchResultsController

I have a TableViewController, a SearchResultsController and a WebViewController. When I click on a cell in the TableViewController it pushes the WebViewController opening a url that is related to the cell.
The TableViewController has a UISearchController which filters the results into the SearchResultsController however when a cell is clicked in the SearchResultsController the WebViewController doesn't get pushed.
Here is the code for the didSelectRowAtIndexPath for the SearchResultsController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
WebViewController *webViewController = [[WebViewController alloc] init];
NSString *extensionURL = (self.searchResults[indexPath.row])[#"url"];
NSURL *baseURL = [NSURL URLWithString:#"http://www.baseurl.com"];
NSURL *URL = [NSURL URLWithString:extensionURL relativeToURL:baseURL];
webViewController.title = (self.searchResults[indexPath.row])[#"title"];
NSLog(#"%#", URL);
webViewController.URL = URL;
[self.navigationController pushViewController:webViewController
animated:YES];
}
I included the NSLog to see if anything happened when a cell was clicked and it does display the url in the console. This makes me think the problem is with the navigationController.
Looking online it seems that the UISearchController should be wrapped in a UISearchContainerViewController which should then be put in the navigationController. I'm still new to app development and can't figure out how or where to do this.
I call my SearchResultsController in the viewDidLoad of my TableViewController like so:
- (void)viewDidLoad
{
[super viewDidLoad];
SearchResultsViewController *controller = [[SearchResultsViewController alloc] initWithStyle:UITableViewStylePlain];
[self addObserver:controller forKeyPath:#"results" options:NSKeyValueObservingOptionNew context:nil];
self.searchController = [[UISearchController alloc] initWithSearchResultsController: controller];
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.delegate = self;
self.definesPresentationContext = YES;
UISearchBar *searchBar = [[UISearchBar alloc] init];
searchBar = self.searchController.searchBar;
searchBar.searchBarStyle = UISearchBarStyleMinimal;
UITextField *searchField = [searchBar valueForKey:#"_searchField"];
searchBar.barTintColor = [UIColor whiteColor];
searchBar.tintColor = [UIColor whiteColor];
self.navigationItem.titleView = searchBar;
}
Is this where I should be embedding my SearchResultsController?
When doing search you will present the NewModalViewController so its simple all you need to do is some steps for pushing viewcontroller when you present search controller
1)self.definesPresentationContext = YES;
After this you should push your viewcontroller like
2) [self.presentingViewController.navigationController pushViewController:sec animated:YES];
Note:Present modalviewcontroller doesnt have Navigation controller so normal push coding wont work as it is not allocated to navigation.
Enjoy.....
You can create a property in your SearchResultsController:
#property (nonatomic, strong) UINavigationController *navController;
Then in your updateSearchResultsForSearchController in your TableViewController set the navController = self.navigationController.
Then you can do this in your SearchResultsController's didSelectRowForIndexPath:
[self.navController pushViewController:webViewController
animated:YES];
This approach worked for me after failing to get Arun's above mentioned solution to work.

Load all Viewcontrollers when application opens

I'm working on a tabbed application for iOS. Because the tabbar icons are loaded in each viewcontroller separately, I was wondering if it is possible to load all the viewcontrollers at once in the background so all the tabbar icons are loaded when the application is launched.
The tabbar makes use of two icons for each tabbar item (selected and unselected), thats why I choose to load the icons in each viewcontroller separately
And otherwise, is there a possibility to load the tabbar icons in the App delegate?
Yes it is possible. You can initialize all controllers and all images in App delegate's didFinishLaunchingWithOptions methods. Here is the example:
UIViewController *locateTabController = [[LocationTabController alloc] initWithNibName:#"LocationTabController" bundle:nil];
UINavigationController *locationTabNavigationController = [[UINavigationController alloc] initWithRootViewController:locateTabController];
// Product Tab
UIViewController *productsTabController = [[ProductsTabController alloc] initWithNibName:#"ProductsTabController" bundle:nil];
UINavigationController *productsTabNavigationController = [[UINavigationController alloc] initWithRootViewController:productsTabController];
// Delivery Tab
UIViewController *nextDeliveryTabController = [[DeliveryTabController alloc] initWithNibName:#"DeliveryTabController" bundle:nil];
UINavigationController *nextDeliveryTabNavigationController = [[UINavigationController alloc] initWithRootViewController:nextDeliveryTabController];
// Order Tab
UIViewController *standingOrderTabController = [[OrderTabController alloc] initWithNibName:#"OrderTabController" bundle:nil];
UINavigationController *standingOrderTabNavigationController = [[UINavigationController alloc] initWithRootViewController:standingOrderTabController];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:locationTabNavigationController, productsTabNavigationController,nextDeliveryTabNavigationController, standingOrderTabNavigationController, nil];
Here navigation controller is provided as every tab controller class had its own navigation.
You can add titles and images at the same time.
/// Adding titles on each of the tab bar controllers
[[self.tabBarController.viewControllers objectAtIndex:0] setTitle:#"Locate"];
[[[self.tabBarController.viewControllers objectAtIndex:0] tabBarItem]setFinishedSelectedImage:[UIImage imageNamed:#"LocateIconActive.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"LocateIconInactive.png"]];
[[self.tabBarController.viewControllers objectAtIndex:1] setTitle:#"Products"];
[[[self.tabBarController.viewControllers objectAtIndex:1] tabBarItem]setFinishedSelectedImage:[UIImage imageNamed:#"ProductsIconActive.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"ProductsIconInactive.png"]];
[[self.tabBarController.viewControllers objectAtIndex:2] setTitle:#"Delivery"];
[[[self.tabBarController.viewControllers objectAtIndex:2] tabBarItem]setFinishedSelectedImage:[UIImage imageNamed:#"NextDeliveryIconActive.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"NextDeliveryIconInactive.png"]];
[[self.tabBarController.viewControllers objectAtIndex:3] setTitle:#"Order"];
[[[self.tabBarController.viewControllers objectAtIndex:3] tabBarItem]setFinishedSelectedImage:[UIImage imageNamed:#"StandingOrderIconActive.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"StandingOrderIconInactive.png"]];
Sub class your UITabBarController and set the images on the viewWillAppear. I found that this is the cleanest way of doing it.
You dont need to load any viewcontroller when application opens for this purpose. All you have to do is set tabbar icon inside each viewcontroller's initialization method like below:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.tabBarItem.image = [UIImage imageNamed:IMAGE_NAME];
[self.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:IMAGE_NAME] withFinishedUnselectedImage:[UIImage imageNamed:IMAGE_NAME]];
self.tabBarItem.title = TITLE;
}
return self;
}
After that when you initialize the viewcontroller object from the AppDelegate, tabbar icon will be set.
viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];

use storyboard with custom UITabbarController

i have been working on this issue for some time now and cannot find a solution to my problem.
i have a tabbar view controller that i have tried to customise with images, i have the custom graphics working however i need to use code to display and init the tabbar's view controllers. i also have a problem with displaying a navigation bar at the top of one of my tabs which i think is connected to how i am initiating the tab view controllers
the storyboard shows that there should be a navigation bar at the top of the medication tab and that the view is connected to the tab bar via a segue
you can see i have tried to use storyboard segues to link my view controllers to the tab bar controller. i have the following code in the MedicationViewController.m
/
// MedicationViewController.m
// fibromapp
//
// Created by jamie mcallister on 08/09/2013.
// Copyright (c) 2013 Jamie McAllister. All rights reserved.
//
#import "MedicationViewController.h"
#import "TakenViewController.h"
#import "MedsListViewController.h"
#import "MedsAlarmViewController.h"
#interface MedicationViewController ()
#end
#implementation MedicationViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
TakenViewController *viewController2 = [[TakenViewController alloc] init];
MedsListViewController *viewController1 = [[MedsListViewController alloc] init];
MedsAlarmViewController *viewController3 = [[MedsAlarmViewController alloc] init];
self.viewControllers = [NSArray arrayWithObjects:viewController1,
viewController2,
viewController3,nil];
UITabBarItem *tab1 = [[UITabBarItem alloc] initWithTitle:#"Medication" image:[UIImage imageNamed:NULL] tag:1];
UITabBarItem *tab2 = [[UITabBarItem alloc] initWithTitle:#"Taken" image:[UIImage imageNamed:NULL] tag:2];
UITabBarItem *tab3 = [[UITabBarItem alloc] initWithTitle:#"Alarms" image:[UIImage imageNamed:NULL] tag:3];
UIImage* sel = [UIImage imageNamed:#"fmtabSel"];
[viewController1 setTabBarItem:tab1];
[viewController2 setTabBarItem:tab2];
[viewController3 setTabBarItem:tab3];
UIImage* tabBarBackground = [UIImage imageNamed:#"fmtab.png"];
UITabBar *tabBar = self.tabBar;
[tabBar setBackgroundImage:tabBarBackground];
[tabBar setSelectionIndicatorImage:sel];
}
return self;
}
- (void)viewDidLoad
{
UITabBar *tabbar = self.tabBar;
NSLog(#"%f %f", tabbar.frame.size.width, tabbar.frame.size.height);//used to find the size of the bar
[super viewDidLoad];
UIImage* tabBarBackground = [UIImage imageNamed:#"fmtab.png"];
UIImage* sel = [UIImage imageNamed:#"fmtabSel"];
UITabBar *tabBar = self.tabBar;
[tabBar setBackgroundImage:tabBarBackground];
[tabBar setSelectionIndicatorImage:sel];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
with this code i get the tab but there is no navigation bar at the top of this tab.
can anybody suggest what i must do to resolve this?
if you require any more information feel free to ask and i will edit it into the bottom of this question.
thanks in advance :)
To have a Navigation bar, you have to put a UINavigationController between the tabbar controller and the first UIViewController.
All can be done in storyboard without needs of writing a line of code.
If you want the navigation bar to be at the top You should fill your tabbar controller with navigation controllers inited with root controllers, not just plain controllers.
Smth like that:
TakenViewController *viewController2 = [[TakenViewController alloc] init];
MedsListViewController *viewController1 = [[MedsListViewController alloc] init];
MedsAlarmViewController *viewController3 = [[MedsAlarmViewController alloc] init];
UINavigationController * nc1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
UINavigationController * nc2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
UINavigationController * nc3 = [[UINavigationController alloc] initWithRootViewController:viewController3];
self.viewControllers = [NSArray arrayWithObjects:nc1,
nc2,
nc3,nil];

Create uiTabBarController programmatically

I want to create a UIView for a UITabBarController
Here is my code for the .h file :
#interface TE : UIViewController <UITabBarControllerDelegate>{
UITabBarController *tabBarController;
}
#property (nonatomic,retain) UITabBarController *tabBarController;
#end
The viewDidLoad method:
UIViewController *testVC = [[T1 alloc] init];
UIViewController *otherVC = [[T2 alloc] init];
NSMutableArray *topLevelControllers = [[NSMutableArray alloc] init];
[topLevelControllers addObject: testVC];
[topLevelControllers addObject: otherVC];
tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate = self;
[tabBarController setViewControllers:topLevelControllers animated:NO];
tabBarController.selectedIndex = 0;
self.view = tabBarController.view;
This creates the tab bar controller, but when I click on a tab bar item, I get an error:
Thread1:Program receive signal: SIGABRT
Edit: I solved the problem by downloading and modifying the version of http://www.iphonedevcentral.com/create-uitabbarcontroller/
You say above that you don't want to create the tabBarController in the appDelegate. Why not? Where else would you create it? The tabBarController has to be the root view controller and cannot be a child of any other view controller.
Btw, make sure you implement:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSUInteger tabIndex = [tabBarController.viewControllers indexOfObject:viewController];
if (viewController == [tabBarController.viewControllers objectAtIndex:tabIndex] ) {
return YES;
}
return NO;
}
Subclass UITabBarController
Override the - (void) loadView method and include the following code
MyCustomViewControllerOne* ctrl1 = [[[MyCustomViewControllerOne alloc] initWithNibName#"MyViewControllerOne" bundle: nil] autorelease];
UIViewController* ctrl2 = [[[UIViewController alloc] init] autorelease];
MyCustomControllerTwo* ctrl3 = [[[UIViewController alloc] initWithObject: myObj] autorelease];
ctrl1.title = #"First tab";
ctrl2.title = #"Second tab";
ctrl3.title = #"Third tab";
ctrl1.tabBarItem.image = [UIImage imageNamed:#"tab_image1.png"];
ctrl2.tabBarItem.image = [UIImage imageNamed:#"tab_image2.png"];
ctrl3.tabBarItem.image = [UIImage imageNamed:#"tab_image3.png"];
[self setViewControllers: #[ctrl1, ctrl2, ctrl3]];
That's pretty much it.
Change self.view = tabBarController.view; to
[self.view addSubview:tabBarController.view]; And it works correctly
Trying changing
self.view = tabBarController.view;
to
[self.view addSubview:tabBarController.view];
See if that helps.
Also try placing this in your -(void)loadView method
- (void)loadView {
UIView *mv = [[UIView alloc] initWithFrame:CGRectMake(0.0, 100.0, 320.0, 480.0)];
self.view = mv;
[mv release];
}
The reason you probably are experiencing a black screen is because you haven't initialized your UIView properly.
#Mehdi, just make your TE a UITabBarController instead of a UIViewController which then has a TabBarController in it. Makes it all the more easy to manage your TabBarController. To respond to some others who have indicated that you can have only one TabBarController as the window's rootViewController. That is not the case. A UITabBarController can be instantiated in multiple places where you need a second level menu navigation. Have a TabBar within a TabBar would not make sense, but having a left Navigation Menu and then having a TabBar on each menu item would make sense.

Resources