Replace one ViewController in TabbarController with NavigationBar - ios

I noticed in Whatsapp there are four tabs. If you disable the access to Contacts, the view in first tab, Favorites, will be replaced with the information view which will guide user to open the Settings.
I was trying to copy this function with following codes (in AppDelegate):
let gotoSettingsVC = UIApplication.sharedApplication().keyWindow?.rootViewController!.storyboard?.instantiateViewControllerWithIdentifier("gotoSettingsViewController") as! GotoSettingsViewController
let tabbarController = UIApplication.sharedApplication().keyWindow?.rootViewController! as! UITabBarController
gotoSettingsVC.tabBarItem = tabbarController.tabBar.selectedItem
tabbarController.viewControllers![tabbarController.selectedIndex] = gotoSettingsVC
The gotoSettingsVC can be shown correct but without Navigation Bar. How to show this View with a Navigation Bar like the normal View in tabbarController?
thank you for any help.

Embed the GotoSettingsViewController in a navigation controller, and set that as one of the tabBar controllers view controller.

Related

Swift: present view controller in same context as other view controllers?

Ok, I have an issue that I cant understand trying to present a view controller (the same instance every time, just like other tab item VCs) from an overall tab bar controller VC. My tab bar controller VC has 3 view controllers that it is connected to via storyboard, so 3 tab bar items appear on the tab bar. When the selectedIndex is changed, these view controllers just appear right there below the subviews of the Tab Bar Controller VC.
These subviews that should always be on top are the nav bar at the top and tab bar at bottom:
And this is great for those 3 view controllers. Problem is I need to access 1 instance of ANOTHER view controller that is NOT shown in the tab bar buttons via a button in the nav bar here.
My problem is no matter how I present it, this VC always pops OVER the tab bar controller VC, covering the tab bar and nav bar.
here I make sure only 1 instance is made:
if podcastVC == nil {
//print("IT IS NIL")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
podcastVC = storyboard.instantiateViewController(withIdentifier: "podcast") as! PodcastViewController
//*NOTE: have to set other vars too, this is temp
podcastVC.urlStr = currentTrackUrl!
podcastVC.originalUrl = currentTrackUrl!
AudioPlayerManager.shared.play(urlString: podcastVC.urlStr)
}
self.show(podcastVC, sender: self)
podcastVC.modalPresentationStyle = .currentContext
podcastVC.definesPresentationContext = false
[1]: https://i.stack.imgur.com/1d6MZ.png
as shown by Swift: How to return to the same instance of my UIViewController
How can I make that VC present in the same context as the tab bar items? I have tried setting the layer of the nav bar to a z position much higher (like 10) but nothing works. What is wrong?
Modal view :
Can works for all view controllers
Is over all other view and need to be pop programatically (adding a button back manually for example)
Push View :
Only works in navigation controllers
Add automatically a back button in the navigationController
you should push VC and it will keep tabbar and nav
you can change modal present style

how to call tab bar view controller by click button function in swift

I have one common tab bar view controller.And i have connected 3 other view controllers with navigation bar and i connect this 3 view controllers with the main tab bar view controller.So now i have 3 tab bar items with 3 view controller.
that is 1.Home 2. Cart 3. feedback
This is fine !!
And now my first view controller(That is my first tab bar view controller) have some table view data and with detail view controller.And in my detail view controller i have one button called "Go to cart".
So the actual flows is when user press Go to cart.It have to move to cart` view controller.Now its moving.
But the problem is .I was not able to see my tab bar items and other items .But if i go normal to each tab bar items its showing all tab bar items.
When i go from my Detail view button click to my Cart tab bar view controller..Then no tab bar items are showing down.
I did all this like demo prototype.Like i drag from button to cart tab bar view controller navigation bar.
But its not showing tab bar why.Please help me out.I don't have any single solution to solve this.I am using swift 2.2.
Thanks.
Updated :
So i need to code some thing like this Right?.But i don't know how to handle this code:
let barViewControllers = sender.destinationViewController as! UITabBarController
let nav = barViewControllers.viewControllers![1] as! UINavigationController
let destinationViewController = nav.topViewController as! CartVC
But i am getting crash in first line :
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
Please help me out
Here is storyboard similar to yours.
Now remove segue from button "go to cart" which is similar to "show second tab" button in my storyboard
Instead provide action to it as follows,
#IBAction func showSecondTab(sender: AnyObject) {
let navController = self.tabBarController?.viewControllers![1] as! UINavigationController
///secondviewcontroller in your case is cart
let secondViewController = navController.viewControllers[0] as! SecondViewController
//set values you want to pass
//lets say I want to pass name to secondVC
secondViewController.name = "ABCD"
self.tabBarController?.selectedIndex = 1
}
you can print and check values in viewDidLoad of secondVC(CartVC).

How to embed in Navigation Controller to a tabbar controller

My initial view controller is a tab bar controller.I want to make the tab bar at top insted of bottom(which I have done using self.tabBarController?.tabBar.frame) . I want to make a navigation bar appear above the tab bar . Can anyone please hep me to do this
A UITabBar should always be at the bottom of the screen.
There is third party implementations of something that is similar to android tabs and might be what you are looking for.
Take a look at https://github.com/HighBay/PageMenu for example.
You can instantiate your view controller with the one of these codes
let VC1 = self.storyboard?.instantiateViewControllerWithIdentifier("storyboardID") as! DemoViewController
OR
let VC2 = YourViewController()
If your view controller is defined at the interface bulider , then go with the first else , go with the second.
Now to construct view array for tabBarController I put NavigationController as the element with rootViewController being the VCs I instantiated .
let tab1 = UINavigationController(rootViewController: VC1)
let tab2 = UINavigationController(rootViewController: VC2)
Describe the tabBarItem images like this
tab1.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "unselectedImage")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal), selectedImage: UIImage(named: "selectedImage")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal))
Finally describe the tabBar array
self.viewControllers = [tab1,tab2] //This will create tabBar with 2 tabs
Your navigation controller will appear at the top with this. You can customize your Navigation Bar. For that see this.
Also don't forget to make your tabBarController the rootViewController in the AppDelegate. Otherwise you will go against Apple guidelines.
Hope this helps. :)
My suggestion is that make viewcontroller and use the UISegmentController to perform the Tab Bar Actions below the Navigation Bar..
thank you

Edit button not displayed in UITabBarController's MoreNavigationController

A UITabBarController is being pushed onto the stack:
let presenter = presentingViewController as! UINavigationController
let tabvc = UITabBarController()
tabvc.viewControllers = vcs
tabvc.customizableViewControllers = vcs
presenter.pushViewController(tabvc, animated: true)
Once presented the more tab button correctly shows, but the edit button to rearrange the tab bars does not. According to the docs on the MoreNavigationController:
The interface for the standard More item includes an Edit button that
allows the user to reconfigure the tab bar. By default, the user is
allowed to rearrange all items on the tab bar. If you do not want the
user to modify some items, though, you can remove the appropriate view
controllers from the array in the customizableViewControllers
property.
My guess is that the tab bar is not happy being in a navigation controller. Any ideas on bringing the edit button back?
You can have both a UINavigationController and a UITabBarController ; using Storyboard helps understand the issue better, any of these solutions will work:
Start out with a UITabBarController as initial view controller
Use presentViewController instead of pushViewController
Use a modal Storyboard segue to perform a modal presentation
Swap out the rootViewController dynamically
Initial View Controller Design
When the Tab Bar Controller is initial View Controller, the Edit button is displayed normally.
Pushed Design
Another Navigation Controller is initial View Controller, using one of 5 adaptive Action Segue:
Show
Custom
-> No Edit button, since it is in direct conflict with the parent UITableViewController.
Show Detail
Present Modally
Popover Presentation
-> Edit button displayed as expected.
Code
1. Program Modal
Using the exact code presented in the question, change the last line:
let presenter = presentingViewController as! UINavigationController
let tabvc = UITabBarController()
tabvc.viewControllers = vcs
tabvc.customizableViewControllers = vcs
presenter.presentViewController(tabvc, animated: true, completion: nil)
2. Storyboard Modal
keeping with the Storyboard theme, create a segue of the correct type, assign an identifier (i.e. presentModallySegue) and the 5 lines above become this single line:
self.performSegueWithIdentifier("presentModallySegue", sender: self)
3. root Swap
A more drastic solution involves swapping out the root view controller at the window level:
let tabvc = UITabBarController()
tabvc.viewControllers = vcs
tabvc.customizableViewControllers = vcs
self.view.window!.rootViewController = tabvc
Conclusion
Either change your design to adopt the Tab Bar Controller as the initial View Controller, or present the Tab Bar Controller modally.
The reason is that navigation bar of your presenter overlaps with the navigation bar of More section.
If you don't show the navigation bar for you navigation controller, you will be able to see the Edit button again when you tap on the More tab.

Change Image of UItabbar Item, Using storyboards

I have the following story board:
As you can see there is a tab bar application with 5 tabs, on the storyboard I've assign the logo for each tab. Now when the user clicks a cell in a particular view I want to change the image of one of the tabs. How can I do this? I don't have an instance of the tab bar view controller or items since storyboards pretty much does all this for me. So my question is what methods do I have to implement to change the image? If I need the tab bar controller how can I get its instance and in which class should I point it to?
Thank you very much,
In any UIViewController class that is part of the Tab Bar hierarchy, all you have to do to get in instance of the tab bar controller is:
//In UIViewController
UITabBarController *tabBarController = self.tabBarController;
You can then change the image as so
//Suppose you want to change the 1st (0th) tab bar image
UITabBarItem * tabItem = [tabBarController.tabBar.items objectAtIndex: 0];
tabItem.image = //whatever image you want to change to
Each UIViewController has a property called tabBarItem which is a UITabBarItem that the tab bar controller uses to set the image representing that controller. You can manipulate that to change the image of the controller in question.
I found that -- at least in Xcode 6.1.1 using Swift -- the direct manipulation of the tabBarItem did not work for me.
However, #borrrden's answer put me on the right track. Apple's documentation for UITabBarController states pretty clearly:
You should never access the tab bar view of a tab bar controller
directly. To configure the tabs of a tab bar controller, you assign
the view controllers that provide the root view for each tab to the
viewControllers property.
...
Tab bar items are configured through their corresponding view
controller. To associate a tab bar item with a view controller, create
a new instance of the UITabBarItem class, configure it appropriately
for the view controller, and assign it to the view controller’s
tabBarItem property.
Therefore, in accordance with that, below is what I came up with that did work for me.
It's written in Swift, and I hope that future readers can translate it accordingly if they need to (I also changed the image names to be super-generic).
I also used UIImage's imageWithRenderingMode method so I could use custom images instead of the shadowy silhouette default images that iOS creates (I would like to credit #NSHeffalump's answer here for that...).
if let viewControllers = tabBarController.viewControllers as? Array<UIViewController> {
var tabBarItemImageNames = ["TabBarItemImage0","TabBarItemImage1","TabBarItemImage2","TabBarItemImage3","TabBarItemImage4"]
var vcIndex = 0
for vc:UIViewController in viewControllers {
let selectedImage = UIImage(named: tabBarItemImageNames[vcIndex])?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
let image = UIImage(named: tabBarItemImageNames[vcIndex])?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
var tabBarItem = UITabBarItem(title: "", image: image, selectedImage: selectedImage)
vc.tabBarItem = tabBarItem
vcIndex++
}
}

Resources