I have created a navigation controller. I added a plus button to the top right of the navigation controller which opens up a new view controller. However, I want the navigation bar to show up on the new screen as well. But it's not showing. What am I doing wrong, or what am I missing? Here is my code:
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var toDoListTextView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//Setting the Title for the nav bar
title = "To Do List"
configureNavigationItems()
}
private func configureNavigationItems(){
/* Adding a button on the top right of the screen
* in the navigation bar/controller.
*/
navigationItem.rightBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .add,
target: self,
action: #selector(didTapPlus)
)
}
#objc func didTapPlus(){
let vc = storyboard?.instantiateViewController(identifier: "makeTask") as! makeTaskViewController
vc.modalPresentationStyle = .fullScreen
vc.title = "Create a Task"
vc.view.backgroundColor = .black
vc.navigationItem.leftBarButtonItem = UIBarButtonItem(
title: "Back",
style: .done,
target: self,
action: nil)
present(vc, animated: true)
}
}
Storyboard
Click Here To See Picture
Demo of App
enter image description here
Each modally-presented view controller gets a brand-new view hierarchy. This means that if you want your MakeTaskViewController to have a navigation bar, you'll need to manually add a navigation controller.
class ViewController: UIViewController {
// ... your code ...
#objc func didTapPlus() {
let vc = storyboard?.instantiateViewController(identifier: "makeTask") as! MakeTaskViewController
vc.modalPresentationStyle = .fullScreen
vc.title = "Create a Task"
vc.view.backgroundColor = .black
vc.navigationItem.leftBarButtonItem = UIBarButtonItem(
title: "Back",
style: .done,
target: vc, /// make sure to set `target` as the new view controller
action: #selector(vc.dismissMe))
/// wrap the new view controller in a navigation controller (this adds the top bar)
let navigationController = UINavigationController(rootViewController: vc)
/// so you can actually see the `Create a Task` text,
navigationController.navigationBar.barStyle = .black
present(navigationController, animated: true)
}
}
/// side note: `MakeTaskViewController` and other classes should be Capitalized
class MakeTaskViewController: UIViewController {
#objc func dismissMe() {
self.dismiss(animated: true)
}
}
Result:
Try this!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var toDoListTextView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//Setting the Title for the nav bar
title = "To Do List"
configureNavigationItems()
}
private func configureNavigationItems(){
navigationItem.rightBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .add,
target: self,
action: #selector(didTapPlus)
)
}
#objc func didTapPlus(){
let vc = storyboard?.instantiateViewController(identifier: "makeTask") as! makeTaskViewController
vc.modalPresentationStyle = .fullScreen
vc.title = "Create a Task"
vc.view.backgroundColor = .black
vc.navigationItem.leftBarButtonItem = UIBarButtonItem(
title: "Back",
style: .done,
target: self,
action: nil)
navigationController?.pushViewController(vc, animated: true)
//present(vc, animated: true)
}
}
😊
Related
In my app I have a push segue from HomeViewController to EditProfileViewController which should have a back button as a leftBarItem and a settings cog as a rightBarItem. The back button displays normally, but the right item is missing. These ViewControllers live happen in the MainNavigationController which has a Navigation Bar.
I tried to define the rightBarButton in ViewDidLoad of the EditProfileVC, I also tried to have a rightBarItem in the storyboard for the View controller.
let buttonItem = UIBarButtonItem(image: settingsIcon, style: .plain, target: self, action: #selector(settingsPressed))
buttonItem.tintColor = UIColor(.settingsIconTint)
navigationItem.rightBarButtonItem = buttonItem
Interestingly if I change the rightBar to a leftBar item, the back button is replaced with the settings cog and works as I expect, but I can't go back to the main page.
let buttonItem = UIBarButtonItem(image: settingsIcon, style: .plain, target: self, action: #selector(settingsPressed))
buttonItem.tintColor = UIColor(.settingsIconTint)
navigationItem.leftBarButtonItem = buttonItem
To set a rightBarButtonItem in a navigationBar,
class HomeViewController: UIViewController {
#IBAction func openEditVC(_ sender: UIButton) {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "EditProfileViewController") as? EditProfileViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
}
}
class EditProfileViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let buttonItem = UIBarButtonItem(title: "Settings", style: .plain, target: self, action: #selector(settingsPressed))
buttonItem.tintColor = .red
navigationItem.rightBarButtonItem = buttonItem
}
#objc func settingsPressed() {
print("Setting Pressed")
}
}
In the above code I've added a UIBarButtonItem with title Settings as a rightBarButtonItem of navigationBar.
No need to configure leftBarButtonItem it not required. Back button is added by default.
Screenshot:
In case it doesn't satisfy your requirement, add a screenshot of what is expected so I can help.
I can not succeed in presenting a UI view and keep the Tab bar in Swift. It does successfully present but there is no tab bar. It appears that presenting a UIView removes the tab bar. Here is my code.
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(goMessages))
Here is what I use.
class MessagesController: UITableViewController {
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(goMessages))
let image = UIImage(named: "new_message_icon")
navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(handleNewMessage))
checkIfUserIsLoggedIn()
tableView.register(UserCell.self, forCellReuseIdentifier: cellId)
// observeMessages()
}
#objc func goMessages() {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let Messages = storyBoard.instantiateViewController(withIdentifier: "Messages") as! MainMSGController
self.present(Messages, animated:true, completion:nil)
You have to push the view controller inside your navigationViewController.
But if you do not have one you should embed your MessagesController inside UINavigationViewController.
(inside your Main.storyboard, select MessagesController then from menu Editor -> Embed in -> Navigation Controller)
and then:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let Messages = storyBoard.instantiateViewController(withIdentifier: "Messages") as! MainMSGController
navigationController?.pushViewController(viewController: Messages, animated: true)
to close it you can:
navigationController?.popViewController(animated: true)
You can't present view controller and keep the tabs. You can only push the view controller if you want to do that. There are some other things required but at the first glance they seem to be implemented properly in your code.
let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: Selector(("HomeTabController")))
self.navigationItem.leftBarButtonItem = backButton
The above code is the creation of button in navigationController but I can create a button cannot write a specific view controller to open.
I have tried with popViewController and popToRootViewController action, need a specific code for opening a particular viewController in swift, with the help of the particular viewController storyboard id and viewcontrollername.
You need to add func name in #selctor() (Swift 4 version)
let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(goToViewController(_:)))
self.navigationItem.leftBarButtonItem = backButton
You need to create a func.
#objc func goToViewController(_ sender: UIBarButtonItem) {
//write code here to open a view controller
let storyboard = "Main"
let viewControllerIdentifier = "HomeVC"
let viewController = UIStoryboard(name: storyboard, bundle: nil).instantiateViewController(withIdentifier: viewControllerIdentifier) as! HomeVC
//push/present "viewController"
}
in this code just replace ChatVC name to your viewcontroller name
#objc func goToViewController(_ sender: UIBarButtonItem) {
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: ChatVC.self) {
self.navigationController!.popToViewController(controller, animated: true)
break
} else {
self.navigationController?.popViewController(animated: true)
}
}
}
I'm relatively new at iOS. I'm struggling, for a while now with this issue. I don't know how to set the logic for presenting popUp when user taps on right bar button item. Basically, it should look like this:PopUp I searched through Google, but I didn't have any luck. I would appreciate if someone would help me with some code.
//My VC
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let rightBarButtonItem = UIBarButtonItem(title: "Share", style: .plain, target: self, action: #selector(clickShare))
rightBarButtonItem.tintColor = UIColor.black
navigationItem.rightBarButtonItem = rightBarButtonItem
// navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Share", style: UIBarButtonItemStyle.plain, target: self, action: #selector(clickShare))
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "backArrow"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(goBack))
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font : UIFont(name: "OpenSans", size: 14)! ], for: .normal)
}
//MARK: - Actions
#objc func goBack() {
navigationController?.popViewController(animated: true)
}
#objc func clickShare() {
//this is where the logic should go
}
//This is my storyboard:
Storyboard
Add following action,
#IBAction func yourButtonClickAction(sender: UIBarButtonItem) {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("YourViewController") as! UIViewController
vc.modalPresentationStyle = UIModalPresentationStyle.Popover
let popover: UIPopoverPresentationController = vc.popoverPresentationController!
popover.barButtonItem = sender
popover.delegate = self
presentViewController(vc, animated: true, completion:nil)
}
Add this action to you barButtonItem.
'YourViewController' = controller consisting of Public, followers options.
I am having trouble creating a UINavigationController toolbar programmatically. I have previously used storyboards to do this successfully but would like to try doing it all in code.
I have created the UIBarButtonItems programmatically, but the actual functions or actions they are supposed to perform when pressed are not working.
To clarify, I am NOT attempting to add UIBarButtonItems to the top bar. I've seen dozens of questions all asking the same thing. I am referring to the toolbar at the bottom that comes with the UINavigationController. This means no "rightBarButtonItem" or "leftBarButtonItem"
Here is the code:
class ProgOneViewController: UIViewController {
var chatRoomsButton: UIBarButtonItem = {
var button = UIBarButtonItem(title: "Chats", style: .plain, target: self, action: #selector(segueToChatRoomController(_:)))
return button
}()
var exploreButton: UIBarButtonItem = {
var button = UIBarButtonItem(title: "Explore", style: .plain, target: self, action: #selector(segueToExploreController(_:)))
return button
}()
var profileButton: UIBarButtonItem = {
var button = UIBarButtonItem(title: "Profile", style: .plain, target: self, action: #selector(segueToProfileController(_:)))
return button
}()
// Flexible spaces that are added in between each button.
var flexibleSpace1: UIBarButtonItem = {
var flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
return flexibleSpace
}()
var flexibleSpace2: UIBarButtonItem = {
var flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
return flexibleSpace
}()
var flexibleSpace3: UIBarButtonItem = {
var flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
return flexibleSpace
}()
var flexibleSpace4: UIBarButtonItem = {
var flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
return flexibleSpace
}()
// These are the functions that are not being called for some mysterious reason.
func segueToChatRoomController(_ sender: Any) {
print("segueing to chat rooms controller")
let chatRoomsController = ChatRoomsViewController()
let navController = UINavigationController(rootViewController: chatRoomsController)
self.present(navController, animated: false, completion: nil)
}
func segueToExploreController(_ sender: Any) {
print("segueing to explore controller")
let exploreController = ExploreCollectionViewController()
let navController = UINavigationController(rootViewController: exploreController)
self.present(navController, animated: false, completion: nil)
}
func segueToProfileController(_ sender: Any) {
print("segueing to profile controller")
let profileController = ProfileTableViewController()
let navController = UINavigationController(rootViewController: profileController)
self.present(navController, animated: false, completion: nil)
}
func setUpToolbar() {
print("setting up toolbar")
self.navigationController?.setToolbarHidden(false, animated: false)
self.navigationController?.toolbar.isUserInteractionEnabled = true
let toolBarItems = [flexibleSpace1, chatRoomsButton, flexibleSpace2, exploreButton, flexibleSpace3, profileButton, flexibleSpace4]
self.setToolbarItems(toolBarItems, animated: true)
// For some reason, these two methods leave the toolbar empty.
//self.navigationController?.setToolbarItems(toolBarItems, animated: true)
//self.navigationController?.toolbar.items = toolBarItems
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
setUpToolbar()
}
}
EDIT*
Here is the code used to instantiate the ProgOneViewController inside a UINavigationController
func pushToTestProgrammaticallyCreatedViews() {
let progOneViewController = ProgOneViewController()
let navController = UINavigationController(rootViewController: progOneViewController)
//navController.isToolbarHidden = false
//progOneViewController.setUpToolbar()
self.present(navController, animated: false, completion: nil)
}
I called this function upon clicking a button in my storyboard-created view controller. The function signature was long in order to specify which viewControllers were tests (created programmatically) :)
first of all you have to make sure that your ProgOneViewController is really included in a UINavigationController. if that is the case the toolbar as well as the barbuttonitems are shown (tried your code in my project).
except of that you have to change all of your barbuttonitem declarations to lazy var so that the references to self within the declarations point to the viewcontroller and target-action works.
feel free to ask if there are any questions :)