Put tab bar to all the viewcontrollers - ios

I've created a Tabbar with UIView what I want is to put this tab bar view on every storyboard this tabbar transfers to.
I tried connecting all the tab bar elements to a button code below and open the storyboard, but the tab bar doesn't show up. any solutions ?
#IBAction func tabBarClick(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Saved", bundle: nil)
print(sender.tag)
if sender.tag == 3 {
guard let savedView = storyboard.instantiateViewController(withIdentifier: "SavedViewController") as? SavedViewController else {
return
}
contentView.addSubview(savedView.view)
savedView.didMove(toParent: self)
}
}

If you created your custom tabbar, the only way to achieve the expected behavior is to create a custom container view controller and put child controllers in it. You can read more about create container controllers here

Related

present UIViewController programatically

When I click on the newPostButton, I want to segue programmatically to the NewPostVC (which is that view on the right side).
However, the view does not show up on the simulator, as you can see, it's completely black.
What is the issue, why isn't the view showing up?
And how to fix that?
Thank you guys
If I understand correctly you are trying present view controller on your Navigation stack so you need to do two thing set storyborad ID and set push viewController here is code :
Set 1:
set Storyboard ID : NewPostVC to your NewPostVC Storyborad
Step 2:
#IBAction func newPostClicked(_ sender: UIButton) {
let storyborad = UIStoryboard(name: "Main", bundle: nil)
if let vc = storyborad.instantiateViewController(withIdentifier: "NewPostVC") as? NewPostVC {
self.navigationController?.pushViewController(vc, animated: true)
}
}

How to do a performSegue to a specific view in Tab Bar Controller from another view (swift 4)

In my iOS app, in a viewController I try to open a specific view in Tab Bar Controller.
I use a performSegue.
First I try to navigate straight to the specific view , but in this case the tab bar disappear
So I try to navigate to the tabViewController, and this lead me to the defult view (the first)
any idea how to navigate to a specific view in TabBarController ?
the performSegue I use:
self.performSegue(withIdentifier: "goToMain", sender: self)
//"goToMain" is my indentipier to the storyboard Segue
I use swift 4
with this code, you don't need segues, you can use when you push some button
let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "tabBarController") as! tabBarLoginViewController
VC1.selectedIndex = 2 //this line says that the view that appears will be third of you tab bar controller
self.navigationController!.pushViewController(VC1, animated: true)
if you want to use segue use this, the segue needs to point of tab bar controller, not a view of tab bar controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "goToMain") {
let vc = segue.destination as! TabBarController
vc.selectedIndex = 2
}
}

Swift multiple subviews and getting back to original TableView

I have created my own TabView the first tab is always the Home tab which contains a TableView . The other 3 Tabs Search, Menu and Inbox are subviews . I can go from
Home to Search then Back to Home and it works
Home to Menu then Back to Home and it works too
Home to Menu then to Search and back to Home brings me back to the Menu subview . I essentially want to eliminate all subviews when clicking the Home Tab . Also each TabView is in it's own controller .
This is my code
From Home Controller to Menu Controller
#IBAction func MenuTabAction(_ sender: UIButton) {
let Popup = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MenuC") as! MenuC
self.addChildViewController(Popup)
Popup.view.frame = self.view.frame
Popup.view.tag = 100
self.view.addSubview(Popup.view)
Popup.didMove(toParentViewController: self)
}
From Menu Controller to Home Controller & Search Controller
#IBAction func HomeTabAction(_ sender: UIButton) {
if let viewWithTag = self.view.viewWithTag(100) {
print("Tag 100")
viewWithTag.removeFromSuperview()
}
}
#IBAction func SearchTabAction(_ sender: UIButton) {
let Popup = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LocalSearchC") as! LocalSearchC
Popup.view.frame = self.view.frame
Popup.view.tag = 100
self.view.addSubview(Popup.view)
Popup.didMove(toParentViewController: self)
}
I am guessing that the remove superview only removes 1 superview at a time so if I go from Subview1 to subview2 then click on the HomeTab it brings me to subview1 instead of the original HomeTab . Is there a way to remove all superview/subviews when clicking the Home Tab ?
Each Tab got it's own view controller. Ideally, you should removeFromSuperview all controllers you're not showing.
At your code, you only removeFromSuperView at HomeTabAction.
Try to change it:
if let viewWithTag = self.view.viewWithTag(100) {
print("Tag 100")
viewWithTag.removeFromSuperview()
}
to
for v in self.view.subviews {
if v.tag == 100 {
v.removeFromSuperview()
}
}
But please, keep in mind that each time a user press any tabs without returning to home (i.e: tapping many times between Menu and Search), it's look like you are just instantiating many controllers, without removing them.
You should remove other Views every time a new one is instantiated. Would be wise to give a unique tag to each view controller and remove the hidden others after every change, not only when returning to Home. Or at least, check if the view controller with a given type already is instantiated before create a new one.
Actually, you don't need to manually instantiate the viewcontrollers (LocalSearch, Menu). TabViewcontrollers can link a vc with each tab item via a segue. In fact, when you add your tabvc to the project, it will come with 2 viewcontrollers, each connected to an item in the tabview, and that's it, you just need to replace them or adapt them, no need to "load" them.
The only scenario where you'd need to do this, is if your buttons were "dynamic", as in, the content to be loaded changes depending on some other circumstances. As long as clicking "Search" goes to LocalSearchViewController, just link it with a segue on the storyboard.

add navigation bar but there is no back button

I created a table view and from there let say a user pressed a cell it will go to ListTavleView but the only problem right now is that whenever a user is in ListTableView there is not back button even thought i already embed a navigation controller
and i want the fist view navigation bar is small title second view navigation bar is large title
enter image description here
Below is my code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showList" {
if let indexPath = tableView.indexPathForSelectedRow {
let items = dataManager.items[indexPath.row]
let controller = (segue.destination as! UINavigationController).topViewController as! ListTableViewController
controller.item = items
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
Below is my storybord setup
Navigation bar with no back button
From the image it seems that view controller is added as a child view controller in current view controller.
There is not need to embedded navigation controller when a cell is pressed becoz there is already a navigation controller at start point so no need to create a new one.(If you present a view controller then you may need to embed navigation controller.)
So the solution is...
Delete the navigation controller.
Connect directly to the destination view controller without navigation controller as there is already.
it is better if you use pushViewController, just get a reference of the other view controller, it will always a back button since you are pushing threw navigation Controller here is a simple example:
let story = UIStoryboard(name: "Main", bundle: nil)
let vc = story.instantiateViewController(withIdentifier: "ExampleViewController") as! ExampleViewController
self.navigationController?.pushViewController(vc, animated: true)
as for the back button, the issue is with your hierarchy.
are you changing the left item of navigation bar in another view controller that might affect navigation bar in your destination view controller.
You are pushing new NavigationController(say Nav.B) to the existing one(Nav.A).
Each navigation controller keeps different navigation stack. The back button is visible when you add viewcontroller to Navigation controller. Read more about UINavigationController.
For your current scenario, you could delete the second navigation controller(i think it not essential) & connect direct segue to ListTableViewController
So this
let controller = (segue.destination as! UINavigationController).topViewController as! ListTableViewController
becomes
let controller = segue.destination as! ListTableViewController
When you need large titles(available 11+), you can add this line in viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
And if it needed only for this Viewcontroller, add in viewWillDisappear() or viewDidDisappear()
navigationController?.navigationBar.prefersLargeTitles = false
If you wanted to have navigation bar back button on next view, then just push the target view on navigation, it will show default navigation back button. No, need to any extra work.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showList" {
if let indexPath = tableView.indexPathForSelectedRow {
let items = dataManager.items[indexPath.row]
guard let controller = segue.destination as? ListTableViewController else {
return
}
controller.item = items
self.navigationController?.pushViewController(controller, animated: true)
}
}}
And if you are pushing the viewcontroller with segue, then no need to add below line self.navigationController?.pushViewController(controller, animated: true)

Why doesn't my UIButton segue behave like a UITableViewCell segue?

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)

Resources