How to set delegate of search bar of viewController using extension? - ios

I created navigation custom class and i wanted to decorate it, I took NavDecoration.swift class and declared extension which has shown in below code, I added search bar code as well in this function, I wanted to set search bar delegate in this extension but its giving error can not assign of type 'UIViewController ' to type 'UISearchBarDelegate
extension UINavigationController {
func makeBlackNavigationbar (viewController: UIViewController, animated: Bool) {
viewController.navigationController?.navigationBar.backgroundColor? = UIColor.blackColor()
let add = UIBarButtonItem(barButtonSystemItem: .Add, target: viewController, action: "addTapped")
let play = UIBarButtonItem(title: "Play", style: .Plain, target: viewController, action: "addTapped")
viewController.navigationItem.rightBarButtonItems = [add, play]
let left = UIBarButtonItem(barButtonSystemItem: .Add, target: viewController, action: "addTapped")
viewController.navigationItem.leftBarButtonItems = [left]
let searchBar = UISearchBar(frame: CGRectZero)
searchBar.placeholder = "Search"
searchBar.delegate = viewController
viewController.navigationItem.titleView = searchBar
}}

You have to conform to UISearchBarDelegate protocol :
extension UINavigationController : UISearchBarDelegate {
...
}

**I have done by changing just few line of code **
extension UIViewController : UISearchBarDelegate {
func makeBlackNavigationbar (viewController: UIViewController, animated: Bool) {
viewController.navigationController?.navigationBar.backgroundColor? = UIColor.blackColor()
let add = UIBarButtonItem(barButtonSystemItem: .Add, target: viewController, action: "addTapped")
let play = UIBarButtonItem(title: "Play", style: .Plain, target: viewController, action: "addTapped")
viewController.navigationItem.rightBarButtonItems = [add, play]
let left = UIBarButtonItem(barButtonSystemItem: .Add, target: viewController, action: "addTapped")
viewController.navigationItem.leftBarButtonItems = [left]
let searchBar = UISearchBar(frame: CGRectZero)
searchBar.placeholder = "Search"
searchBar.delegate = viewController
viewController.navigationItem.titleView = searchBar
}}

Related

replacing UIBarButtonItem with custom view

Found this code to insert the "Done" Button within the decimal keyboard pad and it works as long I don't use a custom view for the button like in this piece of code:
extension UITextField {
func makeKeyboardToolBar(title: String) {
let keyboardToolBar = UIToolbar()
keyboardToolBar.sizeToFit()
let flexibleSpace = UIBarButtonItem(barButtonSystemItem:
UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let bimage = UIImageView(image: UIImage(named: "icon_plus_50"))
let doneButton = UIBarButtonItem(title: title, style: UIBarButtonItem.Style.done, target: self, action: #selector(self.doneClicked))
doneButton.customView = bimage
keyboardToolBar.setItems([flexibleSpace, doneButton], animated: true)
self.inputAccessoryView = keyboardToolBar
}
#objc func doneClicked() {
self.endEditing(true)
}
}
The image appears, but doesn't react. Do not set a custom view works instead, the "title" appears and doneClicked response as appropriate.
There are similar questions but unfort. objective-c...
Any help appreciate.
Don't create or use the UIImageView. Just create the UIBarButtonItem with the image.
let doneButton = UIBarButtonItem(image: UIImage(named: "icon_plus_50"), style: .plain, target: self, action: #selector(doneClicked))
No need to set the customView.

Add UINavigationBar inside view and show buttons

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

IOS Swift Programmatically created navigationController TOOLBAR (bottom bar) item actions not working

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 :)

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
}

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
}
}

Resources