I'm using MvxTabBarViewController that is attributed with:
[MvxFromStoryboard("Main")]
[MvxRootPresentation(WrapInNavigationController = true)]
It does not present "More" button when I have more than five tabs added to the controller. Instead only the first four are shown.
The tabs are MvxViewControllers that are attributed with:
[MvxFromStoryboard("Main")]
[MvxTabPresentation(WrapInNavigationController = false, TabIconName = "icon", TabName = "Tab 1")]
They are presented from ViewWillAppear(bool animated) method using NavigationService.Navigate(TabOneViewModel)
I tried setting WrapInNavigationController to false, but still no luck.
Any help would be appreciated.
When using a Storyboard, in order to add a TabBarController to your application you need to drag and drop a UITabBarViewController instead of a plain UIViewController. Otherwise some properties are not correctly derived (like the TabBar in this case - please see my screenshot).
Just make sure you delete the automatically created TabBar items!
Related
I'm using XCode 13.0, Swift 5.5 and Storyboard. This is a mobile app for iPhone with iOS 15.
I have altogether 7 tabs, all of them with icons. I have 4 tabs and a "More" tab in the tab bar of my app.
3 additional tabs show up after the user clicks on the "More" tab. I'd like the first 2 of these additional tabs to be disabled. They need to be grey coloured and when the user clicks on any of these 2, I'd like to app to do nothing (not to show any page, not to navigate anywhere). I'm using the original UITabBarController and moreNavigationController defined by Apple, I didn't subclass any of them.
On my storyboard I added 2 UIViewControllers to these 2 disabled tabs, but I set them disabled this way:
This didn't work at all. When the user clicks on the 2 disabled tabs, they show 2 empty ViewControllers. I'd expect them not to show anything.
I also tried accessing the moreNavigationController's tabs from the page my UITabBarController first opens. I tried setting these 2 tabs disabled programmatically. However I didn't manage to access these 2 tabs, I only manage to access the main tabs that show up in the tab bar (I don't need to access these). How can I disable and colour grey the tabs that show up after clicking on the More tab?
let moreControllerItems = tabBarController?.moreNavigationController.toolbarItems
if let tabArray = moreControllerItems {
let tabBarItem1 = tabArray[0]
let tabBarItem2 = tabArray[1]
tabBarItem1.isEnabled = false
tabBarItem2.isEnabled = false
}`
This code doesn't work, the moreControllerItems variable is nil. The tabBarController variable isn't nil, I can access my UITabBarController from here, but it doesn't help me much.
I googled this issue lots of different ways but I couldn't find the solution. Any help would be appreciated. I really need to solve this, please write a comment if you have any idea how to solve this. Thank you!
You can disable tabBar items from TabBarController.
class TabVC: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
func disableTabBar(itemNo: Int) {
if let items = tabBar.items, itemNo < items.count {
items[itemNo].isEnabled = false
}
}
And you can access this function from
any child Viewcontroller attached to TabBarController
class MoreVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let tabBarVC = tabBarController as? TabVC {
tabBarVC.disableTabBar(itemNo: 1)
}
}
In short: You cannot disable it. If you want to disable the item in the More Viewcontroller, you have to use a custom Viewcontroller in the fifth Tab
I am explaining here why we cannot do it and what limitations we have.
Apple will show the More tab if items are more than five in the UITabBarController. And more tab holds the UINavigationController which is attached to a kind of UIMoreListController. you can check by
print moreNavigationController.viewControllers[0]
UIMoreListController is not accessible. In your case, the remaining three items are listed in the UIMoreListController. Although we can still access the Viewcontroller's tabBarItem and we can disable it. You can check by clicking the edit option.
But still, users can click on it as long as it is in the UIMoreListController. Because we are not interacting with the tabBar instead we are interacting with the items on the list. Users can't click once you move the item to any of the first four positions using the edit option in the MoreViewcontroller.
I two bar button items and one search bar in a navigation bar added them programmatically
but when i tried to localize this view just from changing the app language it works perfect but it's changing the position of the bar button item (slide menu button) from left to right and i don't want this to be happened and it make the bar button of the men in a side and the view of the menu in another side like this image below:
and this when tapping the menu button to show it it's showing the menu in another place :
so i just want to stop flipping the bar button items when trying to switch between two different languages and i tried to change the semantic of the navigation controller from story board and programmatically and nothing happened and by the way bar button item has no semantic to control by it self and thanks in advance hope you can help me
Use rightAnchor instead of trailingAnchor constraint
For menu you have to set
SideMenuManager.default.leftMenuNavigationController
SideMenuManager.default.rightMenuNavigationController
then choose which one will open depend on your language.
like this
if MOLHLanguage.currentAppleLanguage() == "en"{
let menu = SideMenuManager.default.leftMenuNavigationController!
present(menu, animated: true, completion: nil)
}else {
let menu = SideMenuManager.default.rightMenuNavigationController!
present(menu, animated: true, completion: nil)
}
I use PTCardTabBarController like custom tab bar. I want to hide tab bar in my ViewController. I trying to use in storyboard Hide Bottom Bar on Push or in code: self.tabBarController?.tabBar.isHidden = true. But it not helped me.
When I stat to use PTCardTabBar I have next scheme in storyboard:
TabBarController (with class PTCardTabBarController and module PTCardTabBar) -> NavigationBarController -> ViewController.
Next I launch my app and I see under my PTCardTabBar system iOS tab bar. I use in storyboard Hide Bottom Bar on Push but it is hide only system tab bar and not PTCardTabBar. How to fix it and hide both tab bars?
Taking a quick look at that PTCardTabBar library...
What you see on-screen is not a UITabBar ... it is a UIView. So, any normal actions on a standard Tab Bar Controller's TabBar will not be related.
To hide it, you need to edit PTCardTabBarController.swift and make its customTabBar available to your code:
// make this "open"
open lazy var customTabBar: PTCardTabBar = {
return PTCardTabBar()
}()
Then, when you want to hide the tab bar (for example, in viewDidLoad() in your view controller:
if let ptcTBC = tabBarController as? PTCardTabBarController {
ptcTBC.customTabBar.isHidden = true
}
You'll also (obviously) need to set .isHidden back to false to show it again.
Probably, though, you want to do more than just have it showing or hidden... in which case you could further modify PTCardTabBarController.swift to add a function to animate it into or out-of view (for example).
I have built a simple tab bar with 3 tabs.
I want to run a UI test to make sure that if the user clicks a tab bar item, the correct view controller shows. How would I go about doing that? Below is the code I would start with, just don't know how to write my assertion.
func testTabBarMyProfileButton() {
let tabBarsQuery = XCUIApplication().tabBars
tabBarsQuery.buttons["My Profile"].tap()
}
func testTabBarGraphsButton() {
let tabBarsQuery = XCUIApplication().tabBars
tabBarsQuery.buttons["Graphs"].tap()
}
func testTabBarAboutButton() {
let tabBarsQuery = XCUIApplication().tabBars
tabBarsQuery.buttons["About"].tap()
}
You can access the tabbar button by its position:
app.tabBars.buttons.element(boundBy: 2).tap()
If you have different controls in each view controller shown on each tab bar, you can make assertions if they exist or not (what is expected).
For example if the first tab bar has UILabel named "First name" you can assert if it exists by writing
Let theLabel = app.staticTexts["myValue"]
XCTAssert(theLabel.exists).to(beTrue)
And on the other screens do the same thing for the different controls.
If anyone finds this looking to UI test the contents of another app, I just found a solution..
The tab bar item is a lazy variable and needs to be touched before you can reference a tab bar button by value. Add this line:
tabBarItem.accessibilityIdentifier = "my-snazzy-identifier"
to the viewDidLoad method and you should be able to do this in your UI tests:
app.tabBars.buttons["Button Title"].tap()
You can test the title of the navigation bar.
XCTAssert(app.navigationBars["Graphs"].exists)
See my GitHub repo for a more detailed UI Testing example.
I am using tab bar controller as main and following way-
UITabbarController -> UINavigationController -> UITableViewController (with 5 tab bar & uncheck show navigation bar & made UIView with mail box image as button then click ) -> ViewController (with 5 tab bar & without back button )
I want to get back button as first tab bar title name like < Home
Please let me know the programmatic or structure way.
Thanks
Try to hide titleView label
self.navigationItem.titleView = UIView()
You need to remove the text from the back button. The simplest way is to set it as empty string, like this
self.navigationController?.navigationBar.backItem?.title = ""
You are looking for this
self.navigationController?.navigationBar.backItem?.title = "TEXT"