I have implemented a search controller in a viewController with a table view and also a search controller, the search bar is displayed when search button is taped, search button is a UIBarButtonItem and the searchBar is shown in the navigation controller but I want to make disappear when tap on cancel button, I have tried using serarchBarDelegate protocol but nothing happens on tap here the code
class NewsTVController: UIViewController, UITableViewDataSource, UITableViewDelegate,UISearchResultsUpdating,UISearchBarDelegate{
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
definesPresentationContext = true
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = true
self.searchController.hidesNavigationBarDuringPresentation = false
loadNews()
}
#IBAction func searchButtonTaped(sender:UIBarButtonItem){
print("tap inside")
self.navigationItem.titleView = searchController.searchBar
//self.navigationItem.rightBarButtonItem?.action = #selector(hideSearchBar(:))
// searchController.searchBar.touchesCancelled(UITouch, with: .touchUpInside){
//}
//self.navigationItem.rightBarButtonItem.
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
hideSearchBar()
}
func hideSearchBar() {
print("hay que escpder")
//navigationItem.setLeftBarButtonItem(searchBarButtonItem, animated: true)
//logoImageView.alpha = 0
UIView.animate(withDuration: 0.3, animations: {
self.navigationItem.titleView = nil// = self.logoImageView
self.navigationItem.title = "Eventos"
//self.logoImageView.alpha = 1
}, completion: { finished in
})
}
}
here the pic of the navigation controller with a search button and the search bar
what I want is that when the cancel button is tapped the navigation bar stay as in first pic, no search bar.
and some tips there is a way to hide the back button and the search button when search bar appears.
as i donĀ“t find a way to achive this i found this solution
#IBAction func searchButtonTaped(sender:UIBarButtonItem){
print("tap inside")
self.navigationItem.titleView = searchController.searchBar
searchController.searchBar.setShowsCancelButton(false, animated: false)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Cancelar", style: .plain, target: self, action: #selector(hideSearchBar(sender:)))
//self.searchIcon.is
//self.navigationItem.rightBarButtonItem?.action = #selector(hideSearchBar(:))
// searchController.searchBar.touchesCancelled(UITouch, with: .touchUpInside){
//}
//self.navigationItem.rightBarButtonItem.
}
func hideSearchBar(sender:UIBarButtonItem) {
print("hay que escpder")
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.search, target: self, action: #selector(searchButtonTaped(sender:)))
//logoImageView.alpha = 0
UIView.animate(withDuration: 0.3, animations: {
self.navigationItem.titleView = nil// = self.logoImageView
self.navigationItem.title = "Noticias"
//self.logoImageView.alpha = 1
}, completion: { finished in
})
}
and boila the search bar now dissapear from navigation controller nad the search button is functional since is linked to searchButtonTaped in Interface Builder
Related
I am a bit stuck here. I have a search bar embedded in my navigation bar as the title which I want.
However next I would like to navigate to another view controller containing a UIsearchcontroller in a collection view, and when cancel is tapped the user is brought back to the previous view. (Very similar to Facebook or Instagrams use of the search bar controller)
Is there anyway I can use the search bar as a button to navigate to the next view controller that handles all of the search functions?
This is what I have so far for the search bar.
func setUpNavBar() {
let searchBar = UISearchBar()
searchBar.sizeToFit()
searchBar.searchBarStyle = .minimal
searchBar.placeholder = "Search by username"
searchBar.tintColor = UIColor.lightGray
searchBar.barTintColor = UIColor.lightGray
navigationItem.titleView = searchBar
searchBar.isTranslucent = true
}
Edit
Just to add on to the answer below, if anyone comes across this and you want to get the effect that treats the search bar as a button use
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
self.present(UINavigationController(rootViewController: SearchBarController()), animated: true, completion: nil)
searchBar.setShowsCancelButton(false, animated: true)
return false
}
This way, when you click the search bar, you do not get the effect that shows the search bar active,( if that makes sense). When you tap the search bar, there is no effect, it just takes you to the (real) search view controller then the search bar is active and the keyboard is displayed with a cancel button. I hope that makes sense, if anyone wants an example go to Instagram, FB, or Pinterest and tap on their search bar or search icon and you'll see.
Add UISearchBarDelegate in first view controller. And in searchBarTextDidBeginEditing method present the second view controller.
//ViewController.swift
class ViewController: UIViewController, UISearchBarDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setUpNavBar()
}
func setUpNavBar() {
let searchBar = UISearchBar()
searchBar.delegate = self
searchBar.sizeToFit()
searchBar.searchBarStyle = .minimal
searchBar.placeholder = "Search by username"
searchBar.tintColor = UIColor.lightGray
searchBar.barTintColor = UIColor.lightGray
navigationItem.titleView = searchBar
searchBar.isTranslucent = true
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.present(UINavigationController(rootViewController: SearchViewController()), animated: false, completion: nil)
}
}
//SearchViewController.swift
class SearchViewController: UIViewController {
let searchBar = UISearchBar()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUpNavBar()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
searchBar.becomeFirstResponder()
}
func setUpNavBar() {
searchBar.sizeToFit()
searchBar.searchBarStyle = .minimal
searchBar.placeholder = "Search by "
searchBar.tintColor = UIColor.lightGray
searchBar.barTintColor = UIColor.lightGray
navigationItem.titleView = searchBar
searchBar.isTranslucent = true
}
}
I want to hide navigation bar after a tap
navigationController?.hidesBarsOnTap = true
The navigationBar hides properly after a tap
But after adding a searchController (code below)
let searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController = searchController
My view (cyan color) could not extend correctly
And I also tried rotated it. The search bar appears.
Finally found a solution
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.barHideOnTapGestureRecognizer.addTarget(self, action: #selector(barHideAction(_:)))
let searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
navigationController?.hidesBarsOnTap = true
}
#objc func barHideAction(_ guesture: UITapGestureRecognizer) {
updateFrame()
}
func updateFrame() {
if let nc = navigationController {
let isHidden = nc.isNavigationBarHidden
searchController.searchBar.superview?.isHidden = isHidden
if isHidden {
self.additionalSafeAreaInsets.top = -64 // fixed by a magic num
}
else {
self.additionalSafeAreaInsets.top = 0
}
}
}
example code
I have using EKEventViewController in our app.
Code should like below
class MyEkEventViewController: EKEventViewController {
override func viewDidLoad() {
super.viewDidLoad()
let cancelButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.cancel, target: self, action: #selector(MyEkEventViewController.cancel))
self.navigationController?.navigationItem.setLeftBarButton(cancelButton, animated: false)
//self.navigationController?.navigationItem.leftBarButtonItem = cancelButton
}
}
#objc fileprivate func cancel() {
_ = navigationController?.popViewController(animated: true)
}
}
# My invocation
.
.
.
let eventViewController = MyEkEventViewController()
eventViewController.delegate = self
eventViewController.allowsEditing = true
eventViewController.allowsCalendarPreview = true
eventViewController.hidesBottomBarWhenPushed = true
eventViewController.event = event
self.navigationController?.pushViewController(eventViewController, animated: true)
Back arrow only displayed. But Cancel button is not displayed in left side navigation bar.
I'm currently trying to develop a custom search for an iOS app.
I have managed to get the search controller appearing and the search bar appearing properly, although my only problem is that I need the back button to appear on the right of the navigation bar rather than the left, see below
(As you can see the back button is on the left but I need it to be on the right)
http://imgur.com/qLPoIfG
Here is my code:
import UIKit
class SearchTop10Controller: UITableViewController, UISearchResultsUpdating {
override func viewDidLoad() {
super.viewDidLoad()
let searchController = UISearchController(searchResultsController: self);
self.definesPresentationContext = true;
searchController.searchResultsUpdater = self;
// searchController.hidesNavigationBarDuringPresentation = true;
searchController.dimsBackgroundDuringPresentation = false;
searchController.searchBar.sizeToFit();
self.navigationItem.titleView = searchController.searchBar;
self.tableView.tableHeaderView = searchController.searchBar;
}
override func viewDidAppear(animated: Bool) {
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
//do whatever with searchController here.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
You can add a back button to the right bar item like this:
let backButton : UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "back_icon"), style: UIBarButtonItemStyle.Plain, target: self, action: #selector(back))
self.navigationItem.rightBarButtonItem = backButton
Where back_icon is an image that you are using and back is the following function:
func back() {
self.navigationController?.popViewControllerAnimated(true)
}
To hide the left bar item:
self.navigationItem.leftBarButtonItem = nil
or:
self.navigationItem.hidesBackButton = true
I have 3 pages
Page 1: Menu
Page 2: Menu > Navigation Controller > Map listview
Page 3: Menu > Navigation Controller > Map
It's possible to switch between page 2 and 3 but when you click "Back" it always goes to page 1 and I did this using a custom back button.
After having used the custom back button once the following problem appears:
When I go to page 2 or 3 from the Menu page (Page 1) the navigation title appears and in less than a second it disappears. How is this possible?
These are the functions I am using:
private func hideAndAddNewBackButton(){
if backToRoot{
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "back:")
self.navigationItem.leftBarButtonItem = newBackButton;
self.title = "Locaties"
}
}
func back(sender: UIBarButtonItem) {
if let viewController2 = storyboard!.instantiateViewControllerWithIdentifier("ViewController2") as? ViewController2{
self.navigationController?.pushViewController(viewController2, animated: true);
}
}
func needBackToRoot(){
backToRoot = true;
}
And this is in my viewDidLoad():
var backToRoot:Bool = false;
override func viewDidLoad() {
super.viewDidLoad()
self.hideAndAddNewBackButton();
}
My switch button:
#IBAction func showLijst(sender: AnyObject) {
if let viewController3 = storyboard!.instantiateViewControllerWithIdentifier("Lijst") as? KaartListview{
viewController3.needBackToRoot();
self.navigationController?.pushViewController(viewController3, animated: true);
}
}
In my case problem was creating custom back button and setting in pushed controller
self.navigationController?.navigationBar.topItem?.title = ""
My solutions is :
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.topItem?.title = "SomeTitle"
}
I had a similar issue before and I fixed by using:
navigationController?.navigationBarHidden = false
In the viewDidLoad() function
Like this:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBarHidden = false
}