I have three viewcontrollers that all have buttons switch to a fourth viewcontroller. On this fourth viewcontroller, I have a back button, which I want to take me back to the viewcontroller that I was originally at.
I can't just use the control drag since that only let's you go to a single controller. How can I programmatically have it send the user to the most recent viewcontroller?
import UIKit
class ViewController: UIViewController {
let tabBar = UITabBarController()
var selectedIndex: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tab()
}
#IBAction func goto(_ sender: Any) {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "FrekansViewController") as! FrekansViewController
self.present(nextViewController, animated:true, completion:nil)
}
func tab() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let homeVC = UIViewController()
var streamVC = UIViewController()
var liveVC = UIViewController()
var searchVC = UIViewController()
streamVC = storyboard.instantiateViewController(withIdentifier: "StreamViewController")
liveVC = storyboard.instantiateViewController(withIdentifier: "LiveViewController")
searchVC = storyboard.instantiateViewController(withIdentifier: "SearchViewController")
tabBar.viewControllers = [homeVC,streamVC, liveVC, searchVC]
let itemHome = UITabBarItem(title: "Home", image: UIImage.init(systemName: "house.fill") , tag:0)
let itemStream = UITabBarItem(title: "List", image: UIImage.init(systemName: "waveform.path") , tag:1)
let itemLive = UITabBarItem(title: "Radio", image: UIImage.init(systemName: "play.fill") , tag:2)
let itemSearch = UITabBarItem(title: "Search", image: UIImage.init(systemName: "magnifyingglass"), tag: 3)
homeVC.tabBarItem = itemHome
streamVC.tabBarItem = itemStream
liveVC.tabBarItem = itemLive
searchVC.tabBarItem = itemSearch
self.view.addSubview(tabBar.view)
}
}
Try to embed the controllers inside NavigationController then you can use :
navigationController?.popViewController(animated: true)
This would do the desired functionality for you.
Related
i have a UITabBarViewController that i have created programmatically and i had imported all my 3 UIViewControllers , Now I wanna add Coordinator to my Project and i want to add Coordinator to all my 3 UIViewControllers.
how can i Use It?
class MainTabbarViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// home Tab
let homeStoryboard: UIStoryboard = UIStoryboard(name: "HomeStoryboard", bundle: nil)
let homeTab = homeStoryboard.instantiateViewController(withIdentifier: "HomeViewController")
let homeTabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), selectedImage: UIImage(systemName: "house.fill"))
homeTab.tabBarItem = homeTabBarItem
// search Tab
let searchStoryboard: UIStoryboard = UIStoryboard(name: "SearchStoryboard", bundle: nil)
let searchTab = searchStoryboard.instantiateViewController(withIdentifier: "SearchViewController")
let searchTabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass"), selectedImage: UIImage(systemName: "magnifyingglass"))
searchTab.tabBarItem = searchTabBarItem
// profile Tab
let profileStoryboard: UIStoryboard = UIStoryboard(name: "ProfileStoryboard", bundle: nil)
let profileTab = profileStoryboard.instantiateViewController(withIdentifier: "ProfileViewController")
let profileTabBarItem = UITabBarItem(title: "Profile", image: UIImage(systemName: "person"), selectedImage: UIImage(systemName: "person.fill"))
profileTab.tabBarItem = profileTabBarItem
profileTab.navigationController?.navigationBar.isHidden = true
self.tabBar.tintColor = UIColor(asset: Asset.Colors.yellow)
self.viewControllers = [homeTab, searchTab, profileTab]
}
}
this is my UITabBarController
protocol Coordinator {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}
and this is my Coordinator protocol.
this file should remove and add an other file.
i named TabCoordinator with this Code:
final class TabCoordinator: NSObject, TabBarCoordinatorProtocol {
// Root View Controller
var rootViewController: UIViewController {
return tabController
}
// Empty UITabBarController
let tabController: UITabBarController
// Tab Item Coordinators
let homeCoordinator: HomeCoordinator
let searchCoordinator: SearchCoordinator
let profileCoordinator: ProfileCoordinator
// Initialize
override init() {
tabController = UITabBarController()
var controllers: [UIViewController] = []
// Home Coordinator
homeCoordinator = HomeCoordinator(navigationController: UINavigationController())
let homeViewController = homeCoordinator.rootViewController
homeViewController.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), selectedImage: UIImage(systemName: "house.fill"))
homeCoordinator.start()
// Search Coordinator
searchCoordinator = SearchCoordinator(navigationController: UINavigationController())
let searchViewController = searchCoordinator.rootViewController
searchViewController.tabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass"), selectedImage: UIImage(systemName: "magnifyingglass"))
searchCoordinator.start()
// Profile Coordinator
profileCoordinator = ProfileCoordinator(navigationController: UINavigationController())
let profileViewController = profileCoordinator.rootViewController
profileViewController.tabBarItem = UITabBarItem(title: "Profile", image: UIImage(systemName: "person"), selectedImage: UIImage(systemName: "person.fill"))
profileCoordinator.start()
super.init()
controllers.append(homeViewController)
controllers.append(searchViewController)
controllers.append(profileViewController)
tabController.viewControllers = controllers
tabController.tabBar.tintColor = UIColor(asset: Asset.Colors.yellow)
tabController.tabBar.isTranslucent = false
}
}
and TabBarCoordinatorProtocol file incloude this codes
public protocol TabBarCoordinatorProtocol {
var rootViewController: UIViewController { get }
}
I have tabbar controller which done programmatically. And tab bar is working fine. In stroyboard, i have created firstViewController and assigned class name firstViewController. When i tried to tab on first vc on tab bar controller to navigates to first viewcontroller and it crash. if i give programmatically mean it works fine.
How to navigate from programmatically tab bar controller to storyboard view controller.
here is my code of tab bar controller:
let tabBarCnt = UITabBarController()
func createTabBarController() {
let firstVC = FViewController()
firstVC.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0)
let secondVC = SViewController()
secondVC.tabBarItem = UITabBarItem(tabBarSystemItem: .more, tag: 1)
let thirdVC = ViewController()
thirdVC.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 2)
let fourthVC = ViewController()
fourthVC.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 3)
if UIDevice.current.userInterfaceIdiom == .pad {
let controllerArray = [firstVC, secondVC, thirdVC, fourthVC]
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
} else {
let controllerArray = [firstVC, secondVC]
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
}
}
Here is my firstVC of firstViewController code:
import UIKit
class FViewController: UIViewController, UITabBarDelegate {
#IBOutlet weak var firstBtn: UIButton!
#IBOutlet weak var fview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.blue
// self.fview.backgroundColor = .brown
// Do any additional setup after loading the view.
}
}
Please try below code. you can give view controller identifier by interface builder.
let tabBarCnt = UITabBarController()
func createTabBarController() {
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
let firstVC = storyboard?.instantiateViewControllerWithIdentifier("FViewController")
firstVC.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0)
let secondVC = storyboard?.instantiateViewControllerWithIdentifier("SViewController")
secondVC.tabBarItem = UITabBarItem(tabBarSystemItem: .more, tag: 1)
let thirdVC = storyboard?.instantiateViewControllerWithIdentifier("ViewController")
thirdVC.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 2)
let fourthVC = storyboard?.instantiateViewControllerWithIdentifier("ViewController")
fourthVC.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 3)
var controllerArray = [firstVC, secondVC]
if UIDevice.current.userInterfaceIdiom == .pad {
controllerArray += [thirdVC, fourthVC]
}
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
}
So programatically navigation controller is created and then assigned FirstVC or XVC as root for that navigation controller. This action has been repeated for all tabs.
So, in storyboard instead of dragging view controller you need to take navigation controller. I have attached screenshots.
Default it will give TableViewVC as root for Navigation controller
I am trying to navigate to specific view controller but it is not working.
what i am doing is below
var viewControllers:[UIViewController]!
var firstView : UIViewController!
let storyboard = UIStoryboard(name: "Main", bundle: nil)
firstView = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
viewControllers = [firstView]
#IBAction func BackAction(_ sender: Any) {
for aViewController in viewControllers {
if aViewController is FirstViewController {
self.navigationController!.popToViewController(aViewController, animated: true)
}
}
}
but not working .
Please help me where i am wrong.
Thanks
I use tabBarController to create a music program and I have questions like how to do it as shown in gif
Questions:
How to do so that when you click on tabBarItem, "presentViewController" worked
How to make it so that the photo does not change color and make it round, only in the third tabBarItem
Preferably without libraries
it should be
My TabBarController
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
// меняет цвет фона tabBar
self.tabBar.barTintColor = .white
// меняет цвет UITabBarItem and Title
UITabBar.appearance().tintColor = UIColor(hex: 0x0077fe, alpha: 1)
//меняет цвет background UITabBar
UITabBar.appearance().barTintColor = UIColor.white
// делает фон серым
for item in self.tabBar.items! {
if let image = item.image {
item.image = image.withRenderingMode(.alwaysOriginal)
}
}
//показывает и переходит в контроллеры
let storyBoard = UIStoryboard(name: "Main", bundle:nil)
let controller1 = storyBoard.instantiateViewController(withIdentifier: "main") as! VCMain
let controller2 = storyBoard.instantiateViewController(withIdentifier: "search")
let controller3 = storyBoard.instantiateViewController(withIdentifier: "player")
let controller4 = storyBoard.instantiateViewController(withIdentifier: "bookmark")
let controller5 = storyBoard.instantiateViewController(withIdentifier: "menu")
self.setViewControllers([controller1,controller2,controller3,controller4,controller5], animated: true)
// создает навигационный контроллер для контроллеров
let vc1 = UINavigationController(rootViewController: controller1)
let vc2 = UINavigationController(rootViewController: controller2)
let vc3 = UINavigationController(rootViewController: controller3)
let vc4 = UINavigationController(rootViewController: controller4)
let vc5 = UINavigationController(rootViewController: controller5)
viewControllers = [vc1, vc2, vc3, vc4, vc5]
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(item.tag)
if item.tag == 0{
if GlobalModals.count != 0 {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "player") as? VCPlayer
self.present(vc!, animated: true, completion: nil)
}
}
}
Player
override func viewDidLoad() {
super.viewDidLoad()
let im = Extension.resizeImage(image:GlobalModals[thisSong].ImageView! , targetSize: CGSize.init(width:20, height: 20))
self.tabBarController?.tabBar.items![2].image = im
}
}
The TabBarController doesn't have those option, you need to implement it by subclassing.
You can use this library Animated Tab Bar to achieve the same result with animation.
I created a view and a button on it in tabBarController and created a func that sets the parameters and call it after I set all the view controllers also created a notificationCenter that could change the button image from another controller
class TabBarController: UITabBarController,UITabBarControllerDelegate {
open var playerBtn = UIButton()
//func for NotificationCenter
#objc func imageChange() {
if GlobalModals.count != 0 {
playerBtn.setImage(GlobalModals[thisSong].ImageView, for: .normal)
}
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(imageChange), name: NSNotification.Name(rawValue: "imageChange"), object: nil)
self.delegate = self
//shows and goes to controllers
let storyBoard = UIStoryboard(name: "Main", bundle:nil)
let controller1 = storyBoard.instantiateViewController(withIdentifier: "main") as! VCMain
let controller2 = storyBoard.instantiateViewController(withIdentifier: "search")
let controller3 = storyBoard.instantiateViewController(withIdentifier: "player")
let controller4 = storyBoard.instantiateViewController(withIdentifier: "bookmark")
let controller5 = storyBoard.instantiateViewController(withIdentifier: "menu")
self.setViewControllers([controller1,controller2,controller4,controller5], animated: true)
// creates navigation controller
let vc1 = UINavigationController(rootViewController: controller1)
let vc2 = UINavigationController(rootViewController: controller2)
let vc3 = UINavigationController(rootViewController: controller3)
let vc4 = UINavigationController(rootViewController: controller4)
let vc5 = UINavigationController(rootViewController: controller5)
viewControllers = [vc1, vc2, vc3, vc4, vc5]
self.setupMiddleButton()
}
// TabBarButton – Setup Middle Button and View
func setupMiddleButton() {
playerBtn.frame = CGRect(x: 0, y: 0, width: 45, height: 45)
var playerBtnFrame = playerBtn.frame
playerBtnFrame.origin.y = self.view.bounds.height - playerBtnFrame.height - 2
playerBtnFrame.origin.x = self.view.bounds.width / 2 - playerBtnFrame.size.width / 2
playerBtn.frame = playerBtnFrame
playerBtn.layer.cornerRadius = playerBtnFrame.height/2
playerBtn.layer.masksToBounds = true
playerBtn.contentMode = .scaleAspectFill
let view = UIView()
let width = self.view.frame.width/5
let xWidth = width*2
view.frame = CGRect(x: xWidth , y: playerBtnFrame.origin.y - 2, width: self.view.frame.width/5, height: tabBar.frame.height)
view.backgroundColor = .clear
self.view.addSubview(view)
self.view.addSubview(playerBtn)
playerBtn.setImage(UIImage(named: "home"), for: UIControlState.normal)
playerBtn.addTarget(self, action: #selector(playerButtonAction), for: UIControlEvents.touchUpInside)
self.view.layoutIfNeeded()
}
// Button Touch Action
#objc func playerButtonAction(sender: UIButton) {
if GlobalModals.count != 0 {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "player") as? VCPlayer
self.present(vc!, animated: true, completion: nil)
}
}
}
so I change the image of the button
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageChange"), object: nil)
I have an app with a UITabBarController as my initial view controller.
Currently I'm doing everything in Storyboard but I want to programmatically add a tab to the tab bar based on a user being logged in or not.
I made a TestViewController to test this out. Right now I have two tabs (pictured below). I want to have a third tab positioned on the right programmatically. I put this code in my AppDelegate's didFinishLaunching method. Based on print statements the view controller is being added to the tab bar but it is not appearing in the tab bar then the app loads.
Any suggestions?
func addTabTEST() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabController = storyboard.instantiateViewControllerWithIdentifier("RootTabController") as! UITabBarController
let TestVC = storyboard.instantiateViewControllerWithIdentifier("TestViewController") as! TestViewController
let icon = UITabBarItem(title: "test", image: nil, selectedImage: nil)
TestVC.tabBarItem = icon
print("TAB CONTROLLERS 1: \(tabController.viewControllers)")
tabController.addChildViewController(TestVC)
tabController.viewControllers![2] = TestVC
print("TAB CONTROLLERS 2: \(tabController.viewControllers)")
}
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let nav1 = UINavigationController()
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let first: ViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
nav1.viewControllers = [first]
nav1.setNavigationBarHidden(true, animated: true)
nav1.title = "first"
let nav2 = UINavigationController()
let second: SecondViewController = mainStoryboard.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
nav2.viewControllers = [second]
nav2.setNavigationBarHidden(true, animated: true)
nav2.title = "second"
let nav3 = UINavigationController()
let third: ThirdViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ThirdViewController") as! ThirdViewController
nav3.viewControllers = [third]
nav3.setNavigationBarHidden(true, animated: true)
nav3.title = "third"
let tabController = UITabBarController()
tabController.viewControllers = [nav1,nav2,nav3]
tabController.selectedIndex = 0
self.window!.rootViewController = tabController
self.window?.makeKeyAndVisible()
this is for swift 4
self.window = UIWindow(frame: UIScreen.main.bounds)
let nav1 = UINavigationController()
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let first = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
nav1.viewControllers = [first]
nav1.setNavigationBarHidden(true, animated: true)
nav1.title = "first"
let nav2 = UINavigationController()
let second: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController2") as! HomeViewController2
nav2.viewControllers = [second]
nav2.setNavigationBarHidden(true, animated: true)
nav2.title = "second"
let nav3 = UINavigationController()
let third = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController3") as! HomeViewController3
nav3.viewControllers = [third]
nav3.setNavigationBarHidden(true, animated: true)
nav3.title = "third"
let tabController = UITabBarController()
tabController.viewControllers = [nav1,nav2,nav3]
tabController.selectedIndex = 0
self.window!.rootViewController = tabController
self.window?.makeKeyAndVisible()
if you do not want to use UIStoryboard and if you have three view controllers named oneVC, twoVC, and threeVC you can use (works on Swift 5.3 with iOS 14.2)
let window = UIWindow(frame: UIScreen.main.bounds)
window.backgroundColor = .systemBackground
self.window = window
// Put image path if you want to have an image on your TabBar for this view controller
self.oneVC?.tabBarItem = UITabBarItem(title: "One", image: nil, selectedImage: nil)
self.twoVC?.tabBarItem = UITabBarItem(title: "Two", image: nil, selectedImage: nil)
self.threeVC?.tabBarItem = UITabBarItem(title: "Three", image: nil, selectedImage: nil)
let tabController = UITabBarController()
tabController.viewControllers = [oneVC, twoVC, threeVC]
tabController.selectedIndex = 0
self.window!.rootViewController = tabController
self.window?.makeKeyAndVisible()