Add UINavigationBar inside view and show buttons - ios

I have viewController. Inside is I have UIView
lazy var cView : UIView = {
var view = UIView()
view.backgroundColor = .red
return view
}()
Inside this view I have UINavigationBar
lazy var navigationBar : UINavigationBar = {
let bar = UINavigationBar()
let leftButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.done, target: self, action: #selector(cancel))
bar.topItem?.setLeftBarButton(leftButton, animated: true)
let rightButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(done))
bar.topItem?.setRightBarButton(rightButton, animated: true)
bar.barTintColor = .green
bar.tintColor = UIColor.red
bar.barStyle = .default
bar.isTranslucent = false
return bar
}()
The problem is that in viewController I see only red view with green bar and without any buttons.
What am I doing wrong ? How to make buttons visible ?

bar.topItem UINavigationItem is nil when UINavigationBar is initialized. You can use bar.setItems(items: [UINavigationItem]?, animated: Bool) method to set bar.topItem

Related

UIBarButtonItem doesn't respond to tap

I have a viewController that's embedded in a navigationController. From my viewController I programmatically add three UIBarButtonItem and a UISearchBar. Under the navigationbar I have a WKWebView that is covering the whole screen. The issue it that the UIBarButtonItems doesn't respond to any clicks before I've taped or in any way interacted with the WKWebView. After I tap or scroll the WKWebView the UIBarButtonItems work fine until I perform a search in the UISearchBar. The UIBarButtonItems stops responding again until I interact with the WKWebView.
I have tried adding navigationController?.navigationBar.becomeFirstResponder() in DidAppear and in searchBarTextDidEndEditing as suggested on some forum post. It has no effect on the issue.
This is what I do in DidLoad to initiate the navbar:
self.navigationController?.setNavigationBarHidden(false, animated: true)
searchBar.delegate = self
searchBar.sizeToFit()
searchBar.setImage(UIImage(named: "ssl"), for: .search, state: .normal)
searchBar.searchBarStyle = .minimal
searchBar.showsCancelButton = false
let textField = searchBar.value(forKey: "searchField") as? UITextField
textField?.textAlignment = .center
textField?.leftViewMode = UITextField.ViewMode.never
textField?.clearButtonMode = UITextField.ViewMode.whileEditing
textField?.keyboardType = .URL
textField?.autocapitalizationType = .none
textField?.leftView?.contentMode = .scaleAspectFit
let back = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: self, action: #selector(naviagteBack))
let forward = UIBarButtonItem(image: UIImage(named: "forward"), style: .plain, target: self, action: #selector(naviagteForward))
let reload = UIBarButtonItem(image: UIImage(named: "reload"), style: .plain, target: self, action: #selector(navigateReload))
navigationItem.titleView = searchBar
reload.tintColor = .black
navigationItem.rightBarButtonItem = reload
back.tintColor = .lightGray
forward.tintColor = .lightGray
navigationItem.leftBarButtonItems = [back, forward]
I want the UIBarButtonItems to be active all of the time. Not just after I interact with the WKWebView. And no, it has nothing to do with the capabilities of goBack() e.t.c. I have added print("!") to the button functions and it outputs nothing while in the "unactivated" state.

Hide Nav bar items during search

I have 3 nav bar items in my navigationBar like so:
func setupNavBarButtons() {
let searchImage = UIImage(named: "search_icon")?.imageWithRenderingMode(.AlwaysOriginal)
let searchBarButtonItem = UIBarButtonItem(image: searchImage, style: .Plain, target: self, action: #selector(handleSearch))
let mapBarButtonItem = UIBarButtonItem(title: "Map", style: .Plain, target: self, action: #selector(displayMap))
navigationItem.rightBarButtonItems = [mapBarButtonItem , searchBarButtonItem]
let filterBarButtonItem = UIBarButtonItem(title: "Filter", style: .Plain , target: self, action: #selector(displayFilter))
navigationItem.leftBarButtonItem = filterBarButtonItem
}
When I tap the search icon it calls the function below:
func handleSearch() {
self.navigationItem.titleView = searchController.searchBar
}
I want to hide all navigationBarItems while user is searching and then return nav bar items once user is done searching
You can try like this in your handleSearch method remove the left and right bar button item, After that on searchBarCancelButtonClicked method of UISearchBarDelegate you can set it again that bar items.
func handleSearch() {
searchController.searchBar.hidden = false
self.navigationItem.titleView = searchController.searchBar
searchController.searchBar.becomeFirstResponder()
navigationItem.rightBarButtonItems = nil
navigationItem.leftBarButtonItems = nil
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
self.setupNavBarButtons()
searchController.searchBar.hidden = true
}

How to add title/button to a UINavigationController added inside a UIViewController?

For some reason, I have to add a UINavagationController() inside a UIViewController(), so I did the following in the view controller class:
class someViewController: UIViewController {
private let myNav = UINavigationController()
override func viewDidLoad() {
self.addChildViewController(myNav)
self.view.addSubview(myNav.view)
myNav.view.translatesAutoresizingMaskIntoConstraints = false
myNav.view.topAnchor.constraintEqualToAnchor(self.topLayoutGuide.bottomAnchor).active = true
myNav.view.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
myNav.view.rightAnchor.constraintEqualToAnchor(view.rightAnchor).active = true
myNav.view.heightAnchor.constraintEqualToAnchor(nil, constant: 44).active = true
myNav.didMoveToParentViewController(self)
}
}
The navigation controller is added & showing up correctly. Then I try to add a title (or Done button) to the navigation bar, however the items just don't show up. I tried a few things like this:
self.navigationItem.title = "some title"
myNav.navigationItem.title = "some title"
myNav.navigationItem.rightBarButtonItem = btnDone
What's the right way to do it in this case?
Why don't you use this simple code to add a navigation bar :
let navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 66)) // Offset by 20 pixels vertically to take the status bar into account
// Create a navigation item with a title
let navigationItem = UINavigationItem()
navigationItem.title = "Title"
// Create left and right button for navigation item
let leftButton = UIBarButtonItem(title: "Save", style: UIBarButtonItemStyle.Plain, target: self, action: "btn_clicked:")
let rightButton = UIBarButtonItem(title: "Right", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
// Create two buttons for the navigation item
navigationItem.leftBarButtonItem = leftButton
navigationItem.rightBarButtonItem = rightButton
// Assign the navigation item to the navigation bar
navigationBar.items = [navigationItem]
// Make the navigation bar a subview of the current view controller
self.view.addSubview(navigationBar)

iOS 8 Swift navigation bar title, buttons not showing in tab based application

I am trying to follow this tutorial, this answer, and this answer to create navigation bars for each of my tabs in a tab-based application in iOS 8 / Swift, but no title or buttons on my navigation bar are showing.
Here is what I have so far:
// AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let tabBarController = UITabBarController()
let vc1 = ViewController()
let vc2 = ViewController()
let vc3 = ViewController()
let nc1 = UINavigationController(rootViewController: vc1)
let nc2 = UINavigationController(rootViewController: vc2)
let nc3 = UINavigationController(rootViewController: vc3)
let controllers = [nc1,nc2,nc3]
tabBarController.viewControllers = controllers
nc1.tabBarItem = UITabBarItem(title: "item1", image: nil, tag: 1)
nc2.tabBarItem = UITabBarItem(title: "item2", image: nil, tag: 1)
nc3.tabBarItem = UITabBarItem(title: "item3", image: nil, tag: 1)
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.rootViewController = tabBarController
window?.makeKeyAndVisible()
return true
}
// ViewController.swift
class ViewController: UIViewController, UINavigationBarDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 44))
navigationBar.backgroundColor = UIColor.blueColor()
navigationBar.delegate = self;
let navigationItem = UINavigationItem()
navigationItem.title = "Title"
let leftButton = UIBarButtonItem(title: "Left Button", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
let rightButton = UIBarButtonItem(title: "Right Button", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
navigationItem.leftBarButtonItem = leftButton
navigationItem.rightBarButtonItem = rightButton
navigationBar.items = [navigationItem]
}
func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
return UIBarPosition.TopAttached
}
}
But I am just getting a blank navigation bar on top in the simulator.
You're making a custom UINavigationBar when one is already provided to you with the UINavigationController.
Try this instead in your ViewController:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Title"
let navigationBar = navigationController!.navigationBar
navigationBar.tintColor = UIColor.blueColor()
let leftButton = UIBarButtonItem(title: "Left Button", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
let rightButton = UIBarButtonItem(title: "Right Button", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
navigationItem.leftBarButtonItem = leftButton
navigationItem.rightBarButtonItem = rightButton
}
No need to use a new navigation bar just use your existent navigation bar. Remember what you did here :
let nc1 = UINavigationController(rootViewController: vc1)
So your view controller is already embed inside a navigation controller just use self to access to the navigation items
self.title = "Your Title"
var homeButton = UIBarButtonItem(title: "LeftButton", style: .Plain, target: self, action: "")
var logButton = UIBarButtonItem(title: "RigthButton", style: .Plain, target: self, action: "")
self.navigationItem.leftBarButtonItem = homeButton
self.navigationItem.rightBarButtonItem = logButton
I was unnecessarily creating two navigation bars. The navigation controller comes with a navigation bar, and I changed my ViewController to:
class ViewController: UIViewController, UINavigationBarDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "My Title"
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Left Button", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Right Button", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
}
func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
return UIBarPosition.TopAttached
}
}

Adding bar button items to nav bar without navigation controller in Swift [duplicate]

This question already has answers here:
Adding multiple custom bar buttons to custom nav bar
(3 answers)
Closed 7 years ago.
I'm trying to add multiple bar button items to each side of a custom nav bar.
I'm using the following method but nothing shows up.
There are a few threads on this in Obj-C but I'm struggling to translate the syntax. Is there a workaround for this in Swift?
#IBOutlet weak var navBar: UINavigationBar!
override func viewDidLoad() {
var iconOne = UIImage(named: "iconOne")
var iconTwo = UIImage(named: "iconTwo")
var buttonOne:UIBarButtonItem = UIBarButtonItem(image: iconOne, style: UIBarButtonItemStyle.Plain, target: self, action: nil)
var buttonTwo:UIBarButtonItem = UIBarButtonItem(image: iconTwo, style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.navBar.setItems([buttonOne,buttonTwo], animated: true)
}
If you are using a storyboard, drag a Navigation Bar, and drag a Navigation Item onto the navigation bar.
Then connect an IBOutlet for your UINavigationitem
#IBOutlet weak var navItem: UINavigationItem!
override func viewDidLoad() {
super.viewDidLoad()
let navBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Bookmarks, target: self, action: nil)
navItem.leftBarButtonItem = navBarButton
}
You can also use code:
let navbar = UINavigationBar(frame: CGRect(x: 0, y: 20,
width: UIScreen.mainScreen().bounds.size.width, height: 50))
navbar.tintColor = .lightGray
self.view.addSubview(navbar)
let navItem = UINavigationItem(title: "Test")
let navBarButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: nil)
navItem.leftBarButtonItem = navBarButton
navbar.items = [navItem]

Resources