How to add a search bar to the navigation bar - ios

I'd love to add a search bar managed by UISearchController to the right side of my navigation bar.
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
searchController.searchBar.placeholder = "Search"
searchController.searchBar.searchBarStyle = .Minimal
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: 200.0, height: 44.0)
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: searchController.searchBar)
When I tap on the search bar (so it becomes active) it covers the whole navigation bar (while overlapping everything else) instead of the little part. How can I fix its frame?

Wrapping the search bar in a UIView seems to do the trick.
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: 200.0, height: 44.0)
let barContainer = UIView(frame: searchController.searchBar.frame)
barContainer.backgroundColor = UIColor.clearColor()
barContainer.addSubview(searchController.searchBar)
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: barContainer)

Related

Custom View in Navigationbar titleView disappear iOS Swift

I'm having a problem with the titleView in navigation bar in iOS. I've created a custom view for the titleView, but every time I push another controller, the titleView immediately appear and disappear when I go back to the first view controller. Here's my code.
override func viewDidLoad() {
super.viewDidLoad()
let logo = UIImage(named: "img_appbar_logo")?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
logoContainer = UIView(frame: CGRect(x: 0, y: 0, width: 180, height: 40))
logoContainer.backgroundColor = UIColor.clear
animatedLogo = UIImageView(frame: CGRect(x: 0, y: 0, width: logoContainer.frame.width, height: logoContainer.frame.height))
animatedLogo.contentMode = .scaleAspectFit
animatedLogo.clipsToBounds = true
animatedLogo.image = logo
logoContainer.addSubview(animatedLogo)
navigationItem.titleView = logoContainer
}
I've already fixed the issue related to titleView in Navigation bar. I found out that after I push another controller and pop back, the titleView will be replaced by the view of empty UILabel in the NavigationItem. That's why the titleView appear then disappear.
How I fixed the issue?
I added the custom view directly to the navigation bar. Here's the code
let logo = UIImage(named: "img_appbar_logo")?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
logoContainer = UIView(frame: CGRect(x: 0, y: 0, width: 180, height: 40))
logoContainer.backgroundColor = UIColor.red
animatedLogo = UIImageView(frame: CGRect(x: 0, y: logoContainer.frame.origin.y, width: logoContainer.frame.width, height: logoContainer.frame.height))
animatedLogo.contentMode = .scaleAspectFit
animatedLogo.clipsToBounds = true
animatedLogo.image = logo
logoContainer.addSubview(animatedLogo)
navigationController?.navigationBar.addSubview(logoContainer) <--- new
//navigationItem.titleView = logoContainer <---- old
Then remove the view on viewWillDisappear
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
logoContainer.removeFromSuperview()
}
Set the titleView in viewWillAppear since the titleView gets replaced by the title in the previous controller

How do I change the background of my UISearchbar search field in Swift 5?

How do I change the background of my searchfield? It is set to white now which makes it invisible to the user.
current look
This is my code:
//CHANGE COLOR OF NAVIGATION BAR
navigationController?.navigationBar.barTintColor = UIColor.white
navigationController?.navigationBar.isTranslucent = false
//SEARCH FIELD
let searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self as? UISearchBarDelegate
let frame = CGRect(x: 0, y: 0, width: 300, height: 44)
let titleView = UIView(frame: frame)
searchController.searchBar.backgroundImage = UIImage()
searchController.searchBar.frame = frame
titleView.addSubview(searchController.searchBar)
navigationItem.titleView = titleView
}
It is very simple. You just need to add this line :
searchController.searchBar.backgroundColor = .gray //You can set whichever color you want here

How can i remove this black line from custom navigation bar

Here what i done for custom navigation controller.i was added this code inside of viewDidLoad method.
import UIKit
class Login: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigatonBar()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func navigatonBar(){
let codedLabel:UILabel = UILabel()
codedLabel.frame = CGRect(x: 0, y:-45, width: self.view.frame.width, height: 200)
codedLabel.textAlignment = .center
codedLabel.text = "Login"
codedLabel.textColor = .white
codedLabel.font=UIFont.systemFont(ofSize: 22)
let navigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width,height: 75))
navigationBar.backgroundColor = UIColor.red
navigationBar.isTranslucent = true
navigationBar.barTintColor = .red
self.view.addSubview(navigationBar)
self.view.addSubview(codedLabel)
}
}
but i am getting a Black line in the navigation
It is hard to determine the exact issue since you haven't posted all of your code, but my guess is that you have a UINavigationController with a custom view controller as the root view controller of the UINavigationController. If this is the case, I believe your issue is that you're adding a second navigation bar as a subview of your custom view controller's view. Don't do that. Remove the code below:
let codedLabel:UILabel = UILabel()
codedLabel.frame = CGRect(x: 0, y:-45, width: self.view.frame.width, height: 200)
codedLabel.textAlignment = .center
codedLabel.text = "Login"
codedLabel.textColor = .white
codedLabel.font=UIFont.systemFont(ofSize: 22)
let navigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width,height: 75))
navigationBar.backgroundColor = UIColor.red
navigationBar.isTranslucent = true
navigationBar.barTintColor = .red
self.view.addSubview(navigationBar)
self.view.addSubview(codedLabel)
and customize the UINavigationController's UINavigationBar:
self.title = "Login"
if let navigationBar = self.navigationController?.navigationBar {
navigationBar.backgroundColor = UIColor.red
navigationBar.isTranslucent = true
navigationBar.barTintColor = .red
navigationBar.titleTextAttributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 22), NSAttributedStringKey.foregroundColor: UIColor.white]
}
im pretty sure that is the shadowImage, to remove it just add this navigationBar.shadowImage = UIImage(), doesn't work if you set it to nil (nil is the default value). Edit: I missed the translucent point, set translucent to false, if don't the nav bar will add a UIVisualEffect on the navBar code : navigationBar.isTranslucent = false

Programmatically UISearchBar not showing up

I created a programatically UISearchBar (not UISearchController) and I set it as tableview header. However, it's not showing up. Anyone might know why is that?
Outside of the class:
var searchBar = UISearchBar()
Inside the viewDidLoad method.
searchBar.barTintColor = UIColor(red:0.54, green:0.77, blue:0.80, alpha:1.0)
searchBar.placeholder = "Cauta cheltuieli"
searchBar.backgroundImage = #imageLiteral(resourceName: "searchbarback")
tableView.tableHeaderView = searchBar
tableView.setContentOffset(CGPoint.init(x: 0, y: 44), animated: true)
You forget to give the searchbar any dimension so the size will be zero.
Try setting the dimension by setting the frame or use the constructor with a frame.
let searchbar = UISearchBar(frame: CGRect(x: 0.0, y: 0.0, height: 50.0, width: tableView.frame.width))

UISearchController expands off screen when tapped

We're having a weird issue with using a UISearchController as an item in a navigation bar. It's set as the left bar button item and when a user taps to start searching, the search bar expands to the right off the side of the screen.
Below is the code for creating the UISearchController:
resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.hidesNavigationBarDuringPresentation = false
controller.searchBar.delegate = self
controller.delegate = self
controller.searchBar.frame = CGRect(x: 0, y: 0, width: 266, height: 44.0)
let searchBarView = UIView(frame: controller.searchBar.frame)
searchBarView.addSubview(controller.searchBar)
controller.searchBar.backgroundImage = UIImage(named: "searchBarBG")
controller.searchBar.barTintColor = .white
controller.searchBar.subviews[0].subviews.flatMap(){ $0 as? UITextField }.first?.tintColor = Constants.Colors.Red
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: searchBarView)
return controller
})()
When the screen first loads, it looks like this.
After tapping on the search bar, it changes to look like this.
I have no idea what's causing this. After lots of searching, I tried changing self.definesPresentationContext = false; and self.extendedLayoutIncludesOpaqueBars = true as well as adjusting similar checkboxes in the storyboard. Any tips?
Edit: This only seems to happen on iOS 11. In 10.3, the search bar actually shrinks a little to accommodate the Cancel button but ultimately takes up the same amount of space.
I ended up fixing this by overriding the didPresentSearchController and didDismissSearchController methods as part of the UISearchControllerDelegate.
extension ContactUsViewController: UISearchControllerDelegate {
func didPresentSearchController(_ searchController: UISearchController)
{
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: 266, height: 44.0)
}
func didDismissSearchController(_ searchController: UISearchController)
{
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: 266, height: 44.0)
}
}
If you don't need the added functionality of UISearchBarController you can directly use UISearchBar, which has a more predictable resizing behavor:
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: 200, height: 20))
searchBar.delegate = self
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: searchBar)
Note that if you use the built-in cancel button or other similar features you'll have to manually handle them in the delegate methods.

Resources