Swift UITabBarItem as a UIButton - ios

I tried to implement a UITabBar and now I am not able to retreive a callback from a method when an item was selected. Is there a possibillity to just create a #IBAction func therefore? Or do I need to do something else?

In order to implement UITabBar button, your view controller should conform to UITabBarDelegate protocol. You need to implement:
Swift:
func tabBar(_ tabBar: UITabBar, didSelectItem item: UITabBarItem!)
Objective-c:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
You also need to set the delegate (tabBar.delegate = self) in the viewDidLoad of your ViewController
Edit: Swift 3 answer:
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
}

Your view controller should conform to UITabBarDelegate and implement:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
This method is called when the user selects a tab (i.e. UITabBarItem).

I finally solved the problem. I had some trouble with the Delegator-class and normal class.
This fixed my problem : tabBar.delegate = self in the Main-Controllerclass

Related

iOS on tab bar change

I want to know when the tab in the tab bar changes, so that i can report it to Firebase Analytics. How do i do this.
I tried this
override func viewDidAppear(_ animated: Bool) {
Analytics.logEvent("projects_open", parameters: [:])
}
But i have a feeling that what would also run when i go back to it from another ViewController. I need something that can detect when a tab is opened, not when it becomes visible.
Is there another func that works for this?
Swift 3.0
Use this two delegate methods, and don't forget to assign delegate to self.
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
//MARK: - UITabBarControllerDelegate
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
//MARk: - UITabBarDelegate
}
There is a delegate function on UITabbarController for detecting that a tab was selected:
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
You can also access the selected index like this:
tabController.selectedIndex
If you use only tabBar.in viewDidLoad set tabBar delegate to self and
override func tabBar(_ tabBar: UITabBar, didSelect item:UITabBarItem)
{
//MARk: - UITabBarDelegate
if(tabBar.selectedIndex == 0) {
//Do something
}
else if(tabBar.selectedIndex == 1) {
//Do something.
}
}
and if you use tabBarController use this method.And mark delegate as self
func tabBarController(_ tabBarController: UITabBarController,
didSelect viewController: UIViewController) {
}
Very important Note:
If you want to save which tabBar was previously selected you have to save it on your way.Either use flag or NSUserDefaults according to your wish. The reason i mentioned this because i needed to check which tab has been selected right now in View in one of my project.
Swift 5
Easy way just click on link StakOverFlow screen will open
https://stackoverflow.com/a/60539396/6881070

How do we add action to Tab Bar item

I am using Tab Bar i.e. Bottom bar and have 5 tab bar items, i want to assign a method to each, so that i can navigate to other views on tab bar item click.
I've been looking for some clues, but couldn't make it.
Use UITabBarDelegate.
Implement your class and inherit the protocol by adding after your class definition
#interface MyViewController : UIViewController<UITabBarDelegate>
and then use method tabBar:didSelectItem: in that class
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
// Do Stuff!
// if(item.title == #"First") {...}
}
May be it will help you
In Swift
Implement UITabBarDelegate and use method didSelect
class MyViewController: UIViewController, UITabBarDelegate {
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
}
}
Also create IBOutlet to toolbar
toolbar.delegate = self

Swift: How to execute an action when UITabBarItem is pressed

Currently I have a Tab Bar Controller that is connected to a tableview controller. I'm trying to go to the top of the tableview when I press the tab bar item. I know how to get to the top of the tableview. I just don't know how to do an action when the item is pressed.
You should use UITabBarDelegate with method didSelectItem. Use it as any standard delegate:
class yourclass: UIViewController, UITabBarDelegate {
func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
//This method will be called when user changes tab.
}
}
And do not forget to set your tab bar delegate to self in view controller.
Here is an answer to this question
Basically you do this:
Make sure your view controller is subscribed to the UITabBarDelegate
Set tags in IB for each tab bar item
Implement the didSelectItem method, something like this:
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
if(item.tag == 1) {
// Code for item 1
}
else if(item.tag == 2) {
// Code for item 2
}
}
This will give you access to each tab item tapped event. Hope it helps!
In Swift:
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if(item.tag == 1) {
// Code for item 1
} else if(item.tag == 2) {
// Code for item 2
}
}
SWIFT 3
class yourclass: UIViewController, UITabBarDelegate {
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print("Test")
}
}
And do not forget to set your tabBar delegate to self in viewDidLoad
override func viewDidLoad(){
super.viewDidLoad()
<YOUR TAB BAR NAME>.delegate = self
}
I was having trouble implementing the other answers here. This is a fuller answer. It assumes you are using a UITabBarController (the default if you create a new Tabbed App). This solution will print a message every time a view controller tab button is tapped.
Code
Create a new Swift file called MyTabBarController.swift. Paste in the following code.
import UIKit
class MyTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// tell our UITabBarController subclass to handle its own delegate methods
self.delegate = self
}
// called whenever a tab button is tapped
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if viewController is FirstViewController {
print("First tab")
} else if viewController is SecondViewController {
print("Second tab")
}
}
}
Interface Builder
On your storyboard select the Tab Bar Controller. Then in the Identity inspector, set the class name to MyTabBarController (that is, the name of the class in the code above).
That's all. You can run your app now and be notified whenever the user taps a tab bar item.
Notes
If you need to run a method on a tap, then you can do something like the following in didSelect method.
if let firstVC = viewController as? FirstViewController {
firstVC.doSomeAction()
}
You could do make the FirstViewController implement the delegate and handle everything there. That way you wouldn't need to make any custom UITabBarController subclass and set it in IB. However, having a child do the parent's work seems like the wrong place to do it. Anyway, here is is:
class FirstViewController: UIViewController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
tabBarController?.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
// ...
}
}
The didSelect method above gets called no matter which tab is tapped.
UITabBarControllerDelegate documentation
An alternate solution is to just do something in viewDidAppear in whichever View Controller the tab shows.
First Tab View Controller
import UIKit
class FirstViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("First tab")
}
}
Second Tab View Controller
import UIKit
class SecondViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("Second tab")
}
}
class TestViewController: UIViewController,UITabBarDelegate {
#IBOutlet weak var tabbar: UITabBar!
override func viewDidLoad() {
super.viewDidLoad()
tabbar.delegate = self
}
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(tabBar.items![1]) // The number is tab index
}
}

How do I call something in my UIViewController in the code of my UITabBarViewController?

I want to call a method on a ViewController (type "MatchesViewController", which is on the 3rd tab of my TabBarViewControlleer) if the selected item is NOT of that class.
This is my delegate function for listening when a Tab Bar Item was changed.
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
}
Inside this code, I'd like to detect if the item selected (and its View Controller) is of type "MatchesViewController". If it is NOT of this type, then call method on that controller.
Why not use tabBarController(_:didSelectViewController:) ?
override func tabBarController(tabBarController: UITabBarController,
didSelectViewController viewController: UIViewController)
{
if !(viewController is MatchesViewController) {
let matchesVC = tabBarController.viewControllers?[2] as MatchesViewController
matchesVC.refresh()
}
}

Tab Bar Controller - how to reselect a selected tab

I started with the default Tabbed Application, added some tabs in the Storyboards with their own viewcontrollers, how can I know when a tab that's already selected, get's touched again?
Tab 1 goes to a webview that has loaded other pages, when the user hits the home tab again, when it's still highlighted, I'd like to reload the initial url where it started.
Thanks for any ideas!
The UITabBarControllerDelegate method [– tabBarController:didSelectViewController:] gets called each time the tab bar is touched. The documentation for this API states:
In iOS v3.0 and later, this (selected view controller) could be the same
view controller that was already selected.
So if you detect your specified tab being selected again, you can have this delegate method reload your initial URL.
#interface AHTabBarController () <UITabBarControllerDelegate>
#property (nonatomic, strong) UIViewController* previousViewController;
#end
///
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isEqual:self.previousViewController])
{
NSLog(#"reselect tabbar");
}
self.previousViewController = viewController;
}
Here is a full answer for common use cases.
Create a protocol for handling the reselection
protocol TabInteractionDelegate {
func didReselectTab(at index: Int, with item: UITabBarItem)
}
Call the protocol from a Custom UITabBarController
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
var tabInteractionDelegate: TabInteractionDelegate?
// ...
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
// This will:
// 1. Call when the tab is reselected (i.e. The tab does not switch)
// 2. NOT get called when the tab is switching to a new tab and showing a new view controller
if (tabBar.items?[selectedIndex] == item) {
tabInteractionDelegate?.didReselectTab(at: selectedIndex, with: item)
}
}
}
Listen to changed in the UIViewController you need it in
class CustomViewController: UIViewController, TabInteractionDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Attach the delegate 👇
if let tabBarCont = tabBarController as? ChoiceTabBarController {
tabBarCont.tabInteractionDelegate = self
}
}
// Listen to the change 👇
func didReselectTab(at index: Int, with item: UITabBarItem) {
print("\(index) :: \(item)")
// Here you can grab your scrollview and scroll to top or something else
}
}

Resources