I want to create UISplitView programmatically after pressing a button in a view. For UISplitView, I have two view controllers called as MyTableViewController and MyDetailViewController. This is what I am doing in the action of the button:
UISplitViewController* splitVC = [[UISplitViewController alloc] init];
MyTableViewController* firstVC = [[MyTableViewController alloc] init];
MyDetailViewController* secondVC = [[MyDetailViewController alloc] init];
UINavigationController *leftNavController = [[UINavigationController alloc] init];
[leftNavController pushViewController:firstVC animated:NO];
splitVC.viewControllers = [NSArray arrayWithObjects:leftNavController, secondVC, nil];
AppDelegate * appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:splitVC];
But secondVC (the detail view) doesn't show up. It is just black. Though, the firstVC (the table view) shows up as it should be. What could be the reason?
You should take a look at using [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewIdentifier"], and set an identifier for the view controller in your storyboard. Calling init on a view controller doesn't reference the storyboard you have created, so you need to instead pull the view controller out of the storyboard. The table view worked because its layout is programmed into the UITableViewController class.
Related
I'm facing problem with using UITabBar and UINavigationBar at the same time. My intention is to have tabBar displaying my 3 tabs and navBar on each of these tabs displaying custom name and on some of these tabs additionally displaying some buttons (such as Add button).
I created view controllers in AppDelegate's didFinishLaunchingWithOptions:
AAA *vc1 = [[AAA alloc] init];
BBB *vc2 = [[BBB alloc] init];
CCC *vc3 = [[CCC alloc] init];
Created tabBar and populated it:
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[vc1, vc2, vc3];
Next I have added some titles and images to the tabBarItems of these view controllers which is all working fine, but than I wanted to display navigation bar on top of the application. So I created navigation controller, but I don't know what view controller I need to initiate it with. If I use vc1 and set navController as rootViewController, application displays vc1's view and shows navBar, but doesn't show tabBar.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc1];
self.window.rootViewController = navController;
//self.window.rootViewController = self.tabBarController;
I tried to set tabBarController to init navController and set navController as rootViewController - in this case views, tabBar and navBAr display correctly, but I don't have navBarItems associated with views vc1, vc2, vc3.
This is how I created navBarItems (e.g. in AAA.m):
- (instancetype)init {
self = [super init];
if (self) {
UINavigationItem *navItem = self.navigationItem;
navItem.title = #"name";
}
return self;
}
What do I need to do to make it work all together? Thanks.
EDIT:
I made some modification to the code and now navigation bar is visible, but only on the view controller set in UINavigationController's initWithRootViewController method. For example in following code I can see tab bar on every view and nav bar on the vc2 only. And my intention is to have tab bar and nav bar on every of these three vc.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:vc1, navController, vc3, nil];
self.window.rootViewController = self.tabBarController;
Ok, I have an approach for you...for this you need make changes in storyboard.
Here is a screenshot
Now create a class for UITabBar: class TabBarViewController: UITabBarController
Do not write anything in this class, it just for our reference.
In AppDelegate Class, method: didlaunchFinish:
let vcTabBarViewController = STORYBOARD.instantiateViewController(withIdentifier: "TabBarViewController") as? TabBarViewController
navigationController.viewControllers = [vcTabBarViewController!]
Now in your first view controller which is on 1st tab,
In viewDidLoad method:
paste these lines:
let tabBar = self.tabBarController?.tabBar
let homeTab = tabBar?.items?[0] as UITabBarItem!
let searchTab = tabBar?.items?[1] as UITabBarItem!
let myProfileTab = tabBar?.items?[4] as UITabBarItem!
homeTab?.image = UIImage(named: "home-select")!.withRenderingMode(.alwaysOriginal)
homeTab?.image = UIImage(named: "home")!.withRenderingMode(.alwaysTemplate)
searchTab?.image = UIImage(named: "search-select")!.withRenderingMode(.alwaysOriginal)
searchTab?.image = UIImage(named: "search")!.withRenderingMode(.alwaysTemplate)
I hope this will resolve your problem.
add these line of code on every controller
[self.tabBarController setTitle:#"xyz"];
self.tabBarController.navigationController.navigationBarHidden=NO;
I have a view controller say 'HomeViewController' on which I have added a UITabBarController, which has 4 UITabBarItems. Now what I want is, when I select the HomeViewController no tab should should be selected for the first time and another view should be loaded. I have tried UITabBar instead of UITabBarController but its not working. I have also tried :
tabBarController.selectedViewController=nil; //giving crash
tabBarController.selectedIndex=-1; //not working either
UITabBarItems should be selected when user will click on them.
You have to add UITabBar object on HomeViewController.
In ViewDidLoad you have to add following code:
ViewController1 *controller1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
ViewController2 *controller2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
viewControllersArray = [[NSArray alloc] initWithObjects:controller1,controller2, nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [[NSArray alloc] initWithArray:viewControllersArray];
for(int i = 0; i < tabBarController.tabBar.items.count; i++){
[[tabBarController.tabBar.items objectAtIndex:i] setTitle:[[tabBar.items objectAtIndex:i] title]];
}
isItemSelected = NO;
Also set the tag of tab bar items starting from 0. As 0 for first item, 1 for second item and so on.
and implement delegate method:
(void)tabBar:(UITabBar *)tabBar1 didSelectItem:(UITabBarItem *)item{
if(!isItemSelected){
isItemSelected = YES;
AppDelegate *appDel = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDel.window.rootViewController = tabBarController;
}
tabBarController.selectedIndex = item.tag;
tabBarController.selectedViewController = [viewControllersArray objectAtIndex:item.tag];
}
I think this is not the right way, as Concept of creating TabBar says that " Show the particular controller of related tab". If u do not select any tab than what else you will show on screen, "A black screen ?". so please re-architecture your design.
I am presenting a UITabBarController from another ViewController (HomeViewController). The TabBarController in turn contains UINavigationControllers. However, when from one of the navigation controllers, the user presses the home button, he is required to go to the original ViewController from where the TabBarController was presented.
**tabBarController is not the rootViewController of my window.
Here's my code.
In AppDelegate, I am creating and configuring my TabBarController.
self.custCareVC = [[CustomerCareViewController alloc] initWithNibName:#"CustomerCareViewController_iPhone" bundle:NULL];
self.POController = [[PurchaeOrderViewController alloc] initWithNibName:#"PurchaeOrderViewController_iPhone" bundle:NULL];
self.accAndContactsController = [[AccountsAndContactsViewController alloc] initWithNibName:#"AccountsAndContactsViewController_iPhone" bundle:NULL];
self.customerCareNavController = [[UINavigationController alloc] initWithRootViewController:self.custCareVC];
self.customerCareNavController.title = #"Customer Service";
self.purchaseOrderNavController = [[UINavigationController alloc] initWithRootViewController:self.POController];
self.purchaseOrderNavController.title = #"PO";
self.accAndContactsNavController = [[UINavigationController alloc] initWithRootViewController:self.accAndContactsController];
self.accAndContactsNavController.title = #"Accounts And Contacts";
self.tabBarController = [[UITabBarController alloc] init];
//self.tabBarController.tabBar.backgroundImage = [UIImage imageNamed:#"bluehead.png"];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:self.customerCareNavController, self.accAndContactsNavController, self.purchaseOrderNavController, nil];
In my HomePageViewController, i am presenting it in the following way (on click of a button):
AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
appDel.tabBarController.delegate = self;
[self presentViewController:appDel.tabBarController animated:YES completion:NULL];
Now i need to dismiss my tabBarController after a user presses a Button on any of the navigation controllers (present in the tabBarController) and show the HomeViewController again..!!
You need to create a function in your target controller (which has the power to dismiss the tabBarController) and call that function from your topmost(current) controller/ controller the user is currently interacting with. To achieve the above, you need to first get the tabBarController object from the current controller using parent view controller. Then get the parent view/ root view controller of that controller and performSelector (function) which you created in the first controller.
Be sure to check doesRespondToSelector before you call performSelectorso as to avoid any nasty crashes.
Another way, though pretty hackie is to store a weak reference of the first controller in the AppDelegate and access the same from you current controller.
I am working on a project that uses CoreData one-to-many relationship between folder and files. To show this I am using UISplitViewController, Folders are shown on MasterView and on click of each folder the files are shown on DetailView.Both folders and files are added dynamically.
I have programatically created UISPlitViewController this way
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
FolderViewController = [[FolderViewController alloc] initWithNibName:#"FolderViewController_iPad" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:FolderViewController];
FolderViewController.managedObjectContext = self.managedObjectContext;
fileViewController = [[fileViewController alloc] initWithNibName:#"fileViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController: fileViewController];
FolderViewController.fileViewController = fileViewController;
self.splitViewController = [[UISplitViewController alloc]init];
self.splitViewController.delegate = fileViewController;
self.splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
self.window.rootViewController = self.splitViewController;
}
This splits my ipad in to two. Leftside is FolderViewController and rightside is FileViewController.
My master View never hides, in any Orientation.
I have a button on both Master and DetailView which opens common EditViewController modally through splitViewController this way
- (void)Buttonclick
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
testViewController = [[EditViewController alloc] initWithNibName:#"EditViewController" bundle:nil];
m_editViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[appDelegate.splitViewController presentModalViewController:m_editViewController animated:YES];
}
and when I dismiss this View, I add folders or files accordingly.
I dismiss this view this way
[self dismissModalViewControllerAnimated:YES];
I have few doubts here
1) When I launch the app, all imp(main) functions from Both View Controller gets called.is that ok?
2) When I dismiss this ModalView when opened from DetailView, the delegate functions of NSFetchResultsController get called, which are in MasterView . is that ok?
3) As those functions are getting called, my logic fails in some situations.
Regards
Ranjit
I'm stuck on a problem I really don't know how to solve:
I have a TabBarController defined in my AppDelegate.
UITabBarController *tabBarController = [[UITabBarController alloc] init];
In this TabBarController i have several other NavigationControllers which have UiVieController inside:
ProgramController *programContr = [[ProgrammController alloc] init];
UINavigationController navControllerPro = [[UINavigationController alloc] initWithRootViewController:programContr];
ManualController *manualContr = [[ManualController alloc] init];
UINavigationController navControllerMan = [[UINavigationController alloc] initWithRootViewController:manualContr];
and i add the NavigationController to the TabBarController:
tabBarController.viewControllers = [NSArray arrayWithObjects:navControllerPro,navControllerMan, nil];
I set the tabBarController to the rootViewController:
self.window.rootViewController = tabBarController;
[[self window] makeKeyAndVisible];
That works fine.
Now i want to add a "Login Screen" on top of that.
I did this with:
[tabBarController presentModalViewController:navControllerLogin animated:YES];
Now the TabBarController loads its content in the background even if the LoginViewController is in front. How to load the TabBarController only if a Button is pressed on the LoginViewController?
Please help me.
The tab bar controller is loaded everytime beacuse you set it as the rootViewController.
You should set a normal viewController as the root.. and if the login was succesfull the you should call the tabBarController to be loaded.
In other words, in the appDelegate there should be only the login window.. and in the loginViewController, if the login was ok, you should call and load your tabBarController with all its controller.. using storyboard makes it a lot easier.