How to add a UISearchbar on every view - ios

Or is the easy way to implement the search bar manually on all needed views the correct way?
I have to add a searchbar on nearly every view in my app (in addition to add a button on every views navigationbar). But I am not sure what is the best approach to achieve this target.
Should I subclass a navigationbar or the whole navigation controller?
Or is the easy way to implement the search bar manually on all needed views the correct way?
If I should subclass which class is the right one?
My Idea is to subclass the UINavigationController, add a UISearchBar and after the search results are fetched to open a UITableViewController with the search results.
This is my current approach (without implementing the searchbar delegate just to check if I am on a working solution)
​
import UIKit
class MyNavigationControllerViewController: UINavigationController {
var searchController : UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.backgroundColor = UIColor.red
self.createSearchBar()
}
func createSearchBar() {
let searchBar = UISearchBar()
searchBar.showsCancelButton = true
searchBar.placeholder = "Search"
// searchBar.delegate = self
self.navigationItem.titleView = searchBar
}
}
At least, the debugger enters MyNavigationController but neither the searchbar is visible nor the red navigationbar.

I would suggest using a protocol with an extension that will provide the configuration of the navigation bar and item. Then you can extend any view controller to conform to it and use the protocol's default implementation.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
configureNavigationBar()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController: SearchController { }
protocol SearchController: class { }
extension SearchController where Self: UIViewController {
func configureNavigationBar() {
navigationController?.navigationBar.backgroundColor = UIColor.red
let search = UISearchBar()
search.placeholder = "Search"
search.showsCancelButton = true
navigationItem.titleView = search
}
}

Related

UISearchBarDelegate function -searchBarSearchButtonClicked not working

I am trying to use a delegate function searchBarSearchButtonClicked from UISearchBarDelegate. My search bar is located in the header of UITableViewController. Please can someone advise?
class MySearchTableViewController: UITableViewController, UISearchBarDelegate{
override func viewDidLoad() {
super.viewDidLoad()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
print("clicked!")
}
}
You need to set the delegate of search bar.
(1) mySearchBar.delegate = self
(2) In storyboard, ctrl+drag the search bar to the viewController and choosing delegate.
Please take outlet for your searchbar and confirm delegate.
yoursearchbar.delegate = self
Thanks

Swift: Default Storyboard background Image for all ViewControllers

Is there a way to set (preferably in storyboard IB) an image, which, will serve as the background image for all ViewControllers in the whole storyboard. I don't want to have to add a background image in every ViewController or replicate that in code.
I would could create a UIViewController subclass (e.g. name it DefaultViewController) that sets a specific background color in one of the initialization methods (e.g. viewDidLoad, but don't forget if you override this in a subclass of this class to call it's super method).
Then, let all your view controllers inherit from DefaultViewController
Example code:
class DefaultViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = = UIColor.redColor()
}
}
class SomeViewController: DefaultViewController {
override func viewDidLoad() {
// this call makes the background red, you can also not override this method and it will work too
super.viewDidLoad()
}
}

UISearchController in UINavigationBar push-pop view resizing without Extend Edges

I'm trying to implement a UISearchController with it's searchBar inside the navigationBar of a UINavigationController. This navigationBar has translucent and all Extend Edges turned off in Interface Builder.
The setup is quite simple:
ViewControllerWithSearchController is embedded in a UINavigationController. My viewController code looks like this:
class ViewControllerWithSearchController: UIViewController, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate {
var searchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
definesPresentationContext = true
initializeSearchController()
}
// MARK: - Search
func initializeSearchController() {
// Create and configure the UISearchController
searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.titleView = searchController.searchBar
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// Check the frame of the view
print(view.frame)
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
// Some code here
}
}
When I run this, it works. The frame of the ViewController's view on initial run is (0.0, 64.0, 375.0, 603.0)
This viewController contains a button which pushes a generic viewController onto the stack. When I pop this viewController, the frame of the ViewControllerWithSearchController is unchanged (correct behavior).
However, when I activate the searchBar and then push and pop the second UIViewController (while the searchBar is active), the frame of ViewControllerWithSearchController gets set to (0.0, 0.0, 375.0, 667.0). The view gets extended below the navigationbar, even though this behavior is turned off.
All involved ViewControllers have their Extend Edges options turned off in InterfaceBuilder.
For now, I've implemented a workaround by turning on all the Extend Edges options. This creates a bit of overhead, so I'd rather not do it. Is there a better solution to solve this problem?
I've attached a sample project to illustrate the problem.
Sample project

Unable to make custom action for UITabBarItem

I have problem with UITabBar. I need to make a custom action for Item (UITabBarItem). What do I need to add to make it working?
import UIKit
class ViewController: UIViewController {
#IBOutlet var TabBar: UITabBarItem!
#IBOutlet var Item: UITabBarItem!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationController?.navigationBarHidden
self.navigationItem.hidesBackButton = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tabBar(tabBar: UITabBar!, didSelectItem item: UITabBarItem!) {
var selectedTag = tabBar.selectedItem?.tag
println(selectedTag)
if selectedTag == 0
{
}
else
{
}
}
}
In each ViewController place this function:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//set inital view
}
Then put your code to execute in here and when the view appears it will execute.
Okay then, what I think you want then is not a UITabBar but instead a UIToolBar. From Apple:
"A tab bar is a control, usually appearing across the bottom of the screen in the context of a tab bar controller, for giving the user one-tap, modal access to a set of views in an app. Each button in a tab bar is called a tab bar item and is an instance of the UITabBarItem class. If you instead want to give the user a bar of buttons that each perform an action, use a UIToolbar object."
For the UIToolBar description see:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIToolbar_Class/index.html#//apple_ref/occ/cl/UIToolbar

SWRevealViewController - How to elegantly make the menu disappear with a tap on FrontViewController

I wish for the menu to be hidden when the front view controller is tapped on while the menu is visible.
I need to know an elegant solution to this that doesn't get me to add a gesturerecognizer on all my viewcontrollers
SWRevealViewController provides you with a tap gesture controller which is ready to use. So you can simply add it to your front controller :
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
Moreover, if you want to do it only once, you can create a controller which adds this gesture recognizer, and then inherit from this class. Example in Swift :
class YourFrontViewControllerParentClass : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let revealController = self.revealViewController() {
// add the tap gesture recognizer to the front view (RootViewController) so that the sidebar menu closes when the user taps the front view when the side menu is closed.
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
}
}
}
class YourFrontViewControllerChildClass1 : YourFrontViewControllerParentClass {
override func viewDidLoad() {
super.viewDidLoad()
// specific stuff
}
}
class YourFrontViewControllerChildClass2 : YourFrontViewControllerParentClass {
override func viewDidLoad() {
super.viewDidLoad()
// specific stuff
}
}
class YourFrontViewControllerChildClass3: YourFrontViewControllerParentClass {
override func viewDidLoad() {
super.viewDidLoad()
// specific stuff
}
}

Resources