I've just created a tab UIViewController in Swift, brand new, no code.
I wanted to know how I could change which tab the app starts on. For example, it has view 1 and view 2. At the bottom it has two tabs, tab 1 and tab 2. How could I get it to where the tab and page it starts on is tab 2, view 2. Instead of always opening and starting on the first tab. Thank you for the help!
i think its natural that the UITabViewController shows the first UIViewController.
edit:
The best solution is to subclass the UITabBarController and to change the selected index in it's viedDidLoad() Delegate:
Create a subclass file of UITabBarController (File -> New -> File -> Cocoa Touch Class)
Set this new file as the Class in the UITabBarController of your Storyboard.
Add in the new file:
override func viewDidLoad() {
super.viewDidLoad()
tabBarController.selectedIndex = 1
// or: tabBarController.selectedViewController = myViewController
}
Here's a possible solution. In your viewWillAppear method.
override func viewWillAppear() {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Enter your tabBar storyboard ID here") as! UITabBarController
vc.selectedIndex = 0
self.presentViewController(vc, animated: true, completion: nil)
}
The selectedIndex 0 is the first tabBar. You can change this to whichever tabbar you want to open
Set a storyboard ID in main.storyboard identity ID
Related
Sorry, if it is an essential question.
The scheme is the following:
enter image description here
I want the following:
User taps last Tab
User goes to some ViewController (different from ViewController, actually connected with last Tab)
How to do this (without using segue)?
Thanks a lot in advance!
You can go with instantiateViewController with push when load your tab and push one viewController to another like below:
let next = self.storyboard?.instantiateViewController(withIdentifier: "nextVC")as! nextVC
self.navigationController?.pushViewController(next, animated: true)
You can assign ViewController in you UITabBarController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// create view controllers from storyboard
// Make sure you set Storyboard ID for both the viewcontrollers in
// Interface Builder -> Identitiy Inspector -> Storyboard ID
let clockViewController = storyboard.instantiateViewControllerWithIdentifier("ClockViewController")
let stopWatchViewController = storyboard.instantiateViewControllerWithIdentifier("StopWatchViewController")
// Set up the Tab Bar Controller to have two tabs
let tabBarController = UITabBarController()
tabBarController.viewControllers = [clockViewController, stopWatchViewController]
// Make the Tab Bar Controller the root view controller
window?.rootViewController = tabBarController
I'm trying to create UITabBarController programmatically, adding multiple NavigationControllers to it. When UITabBarController contains one NavigationController - everything works as expected (see image)
But when i add multiple NavigationControllers to UITabBarController each screen becomes black (see another image )
The same black screen is shown when switching between tabs 1, 2, 3, 4 and 5.
Here's the code how UITabBarController is created
class TabBarViewController : UITabBarController{
override func viewDidLoad() {
super.viewDidLoad()
let controllers = [HistoryViewController.self, StatsViewController.self, DashboardViewController.self, ExpenseManagerViewController.self, ProfileViewController.self]
var navControllers: [UINavigationController] = []
controllers.forEach{ ctrl in
navControllers.append(getController(from: ctrl))
}
tabBar.tintColor = Color.green
viewControllers = navControllers
}
private func getController<TType: UIViewController>(from type: TType.Type) -> UINavigationController{
let ctrl = TType()
let navCtrl = UINavigationController(rootViewController: ctrl)
let ctrlName = String.init(describing: type.self).replacingOccurrences(of: "ViewController", with: String.empty)
navCtrl.tabBarItem.title = ctrlName
navCtrl.tabBarItem.image = UIImage(named: ctrlName)
navCtrl.navigationBar.topItem?.title = ctrlName
return navCtrl
}
}
Those UIViewControllers are created using "add Cocoa Touch Class" option and have assigned *.xib files with some minimum design (see one more image)
Any help regarding why all screens become black when multiple (2 and more) NavigationControllers added to TabBarController would be highly appreciated.
Thanks
Clearly you forget how to init the UIViewControllers with xib file:
private func getController<TType: UIViewController>(from type: TType.Type) -> UINavigationController{
let ctrl = TType(nibName: String.init(describing: type.self), bundle: nil)
let navCtrl = UINavigationController(rootViewController: ctrl)
First if you come from any screen then dont insert navigationbar in between that viewcontroller and tabbarcontroller and when you jump to tabbarcontroller set as rootview controller and any tab you want to open than place navigation controller in between. means dont open tabbar controller with navigationbar heirarchy but when u want to open controller with tabs then place navigation controller in between.
I am trying to create segues between my UIViewControllers but am having some difficulties with creating a segue from a UITableViewCell and a UIButton.
When I create a show detail segue through storyboard from a UITableViewCell to a UIViewController it works perfectly and I get the back button showing up. But when I try to create a show detail segue from a UIButton to a UIViewController it doesn't register the navigation stack and presents the screen modally without the back button.
How can I make a successful show detail segue from a UIButton to a viewcontroller? I am new to iOS and am having trouble determining why the UIButton segue doesn't behave the same as the UITableViewCell segue.
Thanks in advance for any help!
Dont connect a segue manually do it through button action.
This is assuming the viewController that has this button is the root view controller of the navigation controller
#IBAction func myButtonTapped(_ sender: Any) {
let vc = self.storyboard!.instantiateViewController(withIdentifier: "YOUR STORYBOARD IDENTIFIER GOE HERE")
self.show(vc, sender: self)
}
If you want to go to a tab of a tab bar controller you have to specify its index. I think you can set it in storyboard but i just go with 0 is on the left then they go up sequentially. so in the example below i want to go to the second tab of the tab bar controller with a modal transition. I assume you can use show here like example above I've just never done it.
let tbc = self.storyboard!.instantiateViewController(withIdentifier: "MyTabController") as! UITabBarController
tbc.selectedIndex = 1 // this is 2nd tab index.. start at 0
tbc.modalPresentationStyle = .overCurrentContext
tbc.modalTransitionStyle = .coverVertical
self.present(tbc, animated: true, completion: { finished in
// you can also do some completion stuff in here if you require it.
// self.view.removeFromSuperview()
// self.navigationController?.navigationBar.removeFromSuperview()
})
let vc = self.storyboard!.instantiateViewController(withIdentifier: "StoryBoardID")
self.navigationController?.pushViewController(vc, animated: true)
I have a TapBarViewController with three Taps in my project.
Now I am trying to put a normal FirstViewController in front of the TapBar ViewController when the application launches.
The FirstViewController should have three buttons for one of the individual Taps of the TapBarViewController.
How can I show the individual Taps of the TapBarViewController by pressing one of the three buttons?
Screenshot
This is the exact answer you are looking for.
Steps:
Add a UIViewcontroller and embed with UINavigationViewController (Editor -> EmbedIn -> NavigationController).
Add Three button + 1 Button (Navigate to TabViewController).
Drag and drop UITabBarController to the storyboard it comes with one default ViewController and place a UILabel named as 'ButtonOneClicked'.
Create Two more ViewControllers and named as 'ButtonTwoClicked' and 'ButtonThreeClicked'.
Connect 'ButtonOne' with FirstViewController and set segue as Show and repeat the same for rest two.
Click on each segue and provide an unique Identifier name.
Then connect the UITabBarController with each UIViewController and choose viewcontrollers
Create a ButtonAction to the Tab Button.
Copy paste the below code in that action.
#IBAction func tabClicked(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "Tab") as! UITabBarController
appDelegate.window?.rootViewController = initialViewController
appDelegate.window?.makeKeyAndVisible()}
Hope this helps you!!
I'm trying to program an iOS App in Swift, where there would be a splash screen before the tab bar screen.
I've looked at:
http://sweettutos.com/2014/01/08/present-a-login-screen-before-the-tab-bar-controller-in-a-uitabbarcontroller-based-app/
Loading a Welcome Screen (Splash Screen) before TabBarController
but both of them require a nib file and I did all my UI in storyboard.
Here's my main question:
The code on the website has something like this:
ControllerName(nibName: "NibName", bundle: nil);
Is there any way I could do the same thing without the nib file and use storyboard?
Assuming that you have the TabBarController already in storyboard, you would add another view controller next to it.
Then you would click on the new view, and in the attributes inspector, check off "Is initial View Controller".
That makes that new view the first thing that comes up when the app is opened. To go to the tabBarController, I would probably have some button on that first view that just has a segue(control drag) to the TabBarController.
What you can do is the following the example in which the tab bar view controller is set as initial viewcontroller you can
Drag and drop another UIViewController from the Object Library into the storyboard object library.
Click on the UIViewController and assign it a StoryboardID
StoryboardID.
In your first view controller class you can access the storyboard and create an instance of the new view controller, that you dragged and dropped before, using the storyboard id, you can do it this in the viewDidAppear override function and present the new view controller modally.
override func viewDidAppear(animated: Bool) {
let myStoryboard = self.storyboard
let modalViewController = myStoryboard?.instantiateViewControllerWithIdentifier("ModalViewControlllerID")
presentViewController(modalViewController!, animated: true, completion: nil)
}
To instantiate programmatically a viewController from a storyboard in a similar way as you would do from a xib with ControllerName(nibName: "NibName", bundle: nil), it's:
UIStoryboard(name: "StoryboardName", bundle: nil)
.instantiateViewController(withIdentifier: "ControllerName")
But you must not forget to set the arbitrary identifier of your viewController in the storyboard under Storyboard ID:
Drag navigationController and viewController to storyboard and make navigationcontroller as initial viewcontroller then push tabbarcontroller from viewcontroller.
Thanks,
Nada Gamal
I just needed to do the same for my project. Here is my solution.
I created a ViewController and made it the Storyboard Entry Point in the Main.storyboard. I previously had a TabViewController with all kinds of setup and needed only 1 change there.
TabBarController should have a StoryboardID, I named my "TabBarID".
I created a new LaunchViewController swift file with that new ViewController added to my Main.storyboard and assigned it in Main.storyboard.
Here is that class. Very simple with a timer that once over the threshold will then present the TabBarViewController in fullscreen.
class LaunchViewController: UIViewController {
var timer = Timer()
var time = 0
var threshold = 2
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundTheme(theme: .orangeWhite)
Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)
}
#objc func updateTimer() {
time += 1
if time > threshold {
timer.invalidate()
guard let storyboard = self.storyboard else {
//failed to find storyboard
return
}
let tabBarController = storyboard.instantiateViewController(identifier: "TabBarID")
tabBarController.modalPresentationStyle = .fullScreen
present(tabBarController, animated: true, completion: nil)
}
}
}