How to present modal view Controller from tabbar - ios

I can't delegate my custom Button. please help
1****TabBarController
func menuButtonAction(sender: UIButton) {
if let count = self.tabBar.items?.count {
let i = floor(Double(count / 2))
self.selectedViewController = self.viewControllers?[Int(i)]
}
}
2****ViewController
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
print(tabBarController.tabBarItem.title)
return true
}
don't print if i touch my custom Button. Another 4 buttons work OK

Related

How to update the value in a VC when a tab is selected from a UITabbarController?

I have a tabbar controller. When the user clicks on one of the tab bar buttons, I need to update a value in the UIPageViewController that is in the target view controller.
I am trying to use a delegate to inform a UIPageViewController which tab bar button was clicked:
protocol PlanTypeDelegate {
func setIntro(thisFlow planType: UITabBarItem)
}
class NewTabBarController: UITabBarController {
var planTypeDelegate : PlanTypeDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// create and handle tab bar button actions
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
planTypeDelegate?.setIntro(thisFlow: item)
}
In my UIPageController I have the following:
class IntroPageController: UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
guard let tabbar = self.parent as? NewTabBarController() else { return }
tabbar.delegate = self
}
}
extension IntroPageController : PlanTypeDelegate {
func setIntro(thisFlow planType: UITabBarItem) {
print("this item:\(planType)")
}
}
Instead I get this error message:
I am new to passing data between VCs so I have no idea how to go about handling this scenario.
EDIT
Same error after update
You can Achieve it like this.. without Delegate ... write setIntro method in IntroPageController i hope it will solve your Issue
class NewTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
}
func tabBarController(_ tabBarController: UITabBarController,
shouldSelect viewController: UIViewController) -> Bool{
if let controller = viewController as? IntroPageController {
controller.setIntro(thisFlow: tabBarController.tabBarItem)
}
return true
}
You can also achieve it through Protocol for that write... All controllers who confirm PlanTypeDelegate can perform action against this method
func tabBarController(_ tabBarController: UITabBarController,
shouldSelect viewController: UIViewController) -> Bool{
if let navController = viewController as? UINavigationController {
if let myViewController = navController.topViewController , let homeController = myViewController as? PlanTypeDelegate {
homeController.setIntro(thisFlow: tabBarController.tabBarItem)
}
} else if let controller = viewController as? PlanTypeDelegate {
controller.setIntro(thisFlow: tabBarController.tabBarItem)
}
return true
}

How to make user can't access the tabbar in home page based on condition

I write the following code inside the function and call that into viewWillAppear method.
I want to disable to Tabbar Bottom items access.
Here TabarVC() is TabBarView controller class name.
let tabbar = TabarVC()
tabbar.tabBar.isUserInteractionEnabled = false
class OneViewController: UIViewController ,UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if viewController.isKind(of: twoViewController.self as AnyClass) {
return true
}
if viewController.isKind(of: threeViewController.self as AnyClass) {
return false
}
}
}

Present modally when tab on tabbar

I am trying to add a new tabbar item in my tabbar, and when tapping the item, the viewcontroller connected to it, should be displayed fullscreen and as a modal.
I have connected the desired VC to the tabbar as a root (in order for it to be displayed in the tabbar).
I have tried the following code, but the VC is displayed as normal behaviour for a tabbar viewcontroller.
How can I make it show modally fullscreen instead?
class tabBarViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
let isModalView = viewController is dreamteamViewController
if isModalView {
// you can refactor this part of the code
let cameraController = UINavigationController(rootViewController: dreamteamViewController())
self.present(cameraController, animated: true, completion: nil)
return false
} else {
return true
}
}
Change your viewDidLoad like this to set the delegate callback to correct instance:
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
Define and storyboard identifier for your desired viewcontroller in the story board
Change your shouldSelect method like below:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool
{
let isModalView = viewController is DesiredViewController
if isModalView {
// you can refactor this part of the code
let mainStory = UIStoryboard(
name: "Main", bundle: nil
)
let desiredVC = mainStory.instantiateViewController(
withIdentifier:"YourIdentifier"
) as UIViewController
let navBar = UINavigationController.init(rootViewController: desiredVC)
self.present(navBar, animated: true, completion: nil)
return false
} else {
return true
}
}
I posted a project in my github that present one of the tabbar item modally. Please check it from https://github.com/Hbehboodi/Navigation-TabbarWithModalTabItem if any thing is not clear.

Trigger image picker on UITabBarController button click

I have made a tabbar in storyboard with 4 bar items, I connected all of them to other view controllers by rightclick dragging and setting viewcontroller segue. Now for the second button i want to show an imagepicker instead of a viewcontroller. When i delete the second segue from storyboard in UITabBarController, my 4th bar item disappears.
This is my tabview controller
class BaseTabBarController: UITabBarController, UITabBarControllerDelegate {
let arrayOfImageNameForUnselectedState = ["home", "explore", "addIcon", "notification", "accountIcon"]
let arrayOfImageNameForSelectedState = ["homeFilled", "exploreFilled", "addIcon", "notificaitonFilled", "accountIcon"]
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
if let count = self.tabBar.items?.count {
for i in 0..<count {
let imageNameForSelectedState = arrayOfImageNameForSelectedState[i]
let imageNameForUnselectedState = arrayOfImageNameForUnselectedState[i]
self.tabBar.items?[i].selectedImage = UIImage(named: imageNameForSelectedState)?.withRenderingMode(.alwaysOriginal)
self.tabBar.items?[i].image = UIImage(named: imageNameForUnselectedState)?.withRenderingMode(.alwaysOriginal)
}
}
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if tabBar.items?.index(of: item) ?? 0 == 2 {
//Clicked add tab, cancel segue and show imagepicker
} else {
selectedTabindex = tabBar.items?.index(of: item) ?? 0
}
}
}
How do I show image picker on 2nd bar button click
Do not Delete Second segue from storyboard put dummy view controller to show tab button inside tabbar. Implement UITabBarController controller's delegate method in subclass of UITabBarController and return false in shouldSelect method for second viewcontroller and present ImagePicker View for there.
Code:
class BaseTabBarController : UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override var prefersStatusBarHidden: Bool {
return false
}
}
extension BaseTabBarController : UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if self.viewControllers?.index(of:viewController) == 1 {
// TO Do code for Image Picker and Present it
return false
} else {
return true
}
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
}
}

How to pause/resume/cancel an event in iOS

I have an UITabBarController and sometimes in didSelectItem delegate I need to pause the event and present a popup. If user confirmed the event resumes and if not, event will be canceled. Here's my code:
class YC_TabBarController: UITabBarController {
var prevIndex: Int!
var exitAction: (()->Bool)?
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
self.prevIndex = self.selectedIndex
if self.prevIndex == 2 {
guard self.exitAction != nil else {return}
//pause
let isExitAccepted: Bool = self.exitAction!()
//if true -> resume
//if false -> prevent from switching tab
}
}
}
How can I do that? Please Help
You should confirm to UITabBarControllerDelegate in first view controller and return false if the desired view controller is selected in shouldSelect viewController. Then you should show your popup view. In popup view ok/confirm button you can change selected view controller of the self.tabBarController
class ViewController: UIViewController,UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if viewController is SecondViewController {
//show alert
return false
} else {
return true
}
}
func popUpOkAction(_ sender:UIButton) {
if let secVC = self.tabBarController?.viewControllers?.first(where: { $0 is SecondViewController }) {
self.tabBarController?.selectedViewController = secVC
}
}
}
If you want to perform this from multiple view controllers rather than
firstViewController you can confirm to UITabBarControllerDelegate in
YC_TabBarController itself.

Resources