I am working on pretty simple animation in navigation bar: I have navigationbar bar with 2 buttons on the (right). On search icon tap I animate nav bar so it hides both button and search icon and shows search bar. On cancel button tap it does the opposite. Simple
lazy var searchBar:UISearchBar = UISearchBar()
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
searchBar.delegate = self
searchBar.backgroundColor = UIColor.darkGray
searchBar.tintColor = UIColor(red: 140/255, green: 195/255, blue: 65/255, alpha: 1.0)
}
On tap of search button search bar is added to navigation bar,but its slightly cut's off on the left as well as right side.
#IBAction func subjectTapped(_ sender: Any) {
self.navigationItem.setRightBarButtonItems(nil, animated: true)
self.navigationItem.setLeftBarButtonItems(nil,animated: true)
self.navigationItem.titleView = nil
searchBar.placeholder = "I am looking for ..."
searchBar.alpha = 0
self.navigationItem.titleView = searchBar
UIView.animate(withDuration: 0.5, animations: {
self.searchBar.alpha = 1
}, completion: { finished in
self.searchBar.becomeFirstResponder()
})
}
Please tell me what am i doing wrong and whats the fix for this problem
Related
I have a navigation controller in my main View where it includes a searchBar. Then when it goes to second View (without searchBar) there is a little jump on the screen, and same thing happens when I go back to first View.
Here is my Navigation controller code for first viewController:
func configureNavBar() {
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.barTintColor = .mainPink()
navigationController?.navigationBar.barStyle = .black
searchBar = UISearchBar()
searchBar.delegate = self
searchBar.tintColor = .white
navigationItem.titleView = searchBar
searchBar.showsCancelButton = true
}
Second:
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.barTintColor = .mainPink()
navigationController?.navigationBar.barStyle = .black
Is there any way to eliminate this 'jump' ?
This question actually contains two different issues:
1- In case of "Large Navigation Bar" suddenly collapsed when navigating to another View Controller:
The TableView scrolling is the main reason, Try the following:
self.tableView.contentInsetAdjustmentBehavior = .never
You can set it from "Size Inspector" in storyboard also.
It adjusts its scroll position corresponding to the SafeArea.
2- The case of "Default Navigation Bar" that contains SearchBar in its Navigation Item's title view:
The main reason is that the search bar is added with height "56" by default
Regarding a black line that appears under the navigation bar of the pushed view controller, So you can fix it with the following:
// Inside ViewDidLoad of the Pushed View Controller
self.extendedLayoutIncludesOpaqueBars = true
OR
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.view.setNeedsLayout()
navigationController?.view.layoutIfNeeded()
}
For preventing the NavigationBar to be extended at all when putting the SearchBar like this:
You need to create a custom view with a fixed height frame and add this search bar inside it, check the following:
class SearchBarViewHolder: UIView {
let searchBar: UISearchBar
init(customSearchBar: UISearchBar) {
searchBar = customSearchBar
super.init(frame: CGRect.zero)
addSubview(searchBar)
}
override convenience init(frame: CGRect) {
self.init(customSearchBar: UISearchBar())
self.frame = frame
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
searchBar.frame = bounds
}
}
// Adding Search bar
let searchBarViewHolder = SearchBarViewHolder(customSearchBar: searchBar)
searchBarViewHolder.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)
navigationItem.titleView = searchBarViewHolder
I have a tableView. I set the all settings about searchController ( Search Bar in Large Navigation Bar ) - ( open / close when scroll tableview ). I implemented rightBarButtonItem which name is 'Close' . I want to hide/close tableView and Search Bar with programmatically. I can hide tableView but not SearchBar.
When I do isHidden for SearchBar , The Large Navigation Bar doesnt shrink to normal size.
Pic 1. Opened search bar with scroll down.
Pic 2. Not Hidden Large Navigation Bar with programmatically ( searchar.isHidden not implemented here )
Thanks in advance.
I tried this before but not run
tableView.setContentOffset(.zero, animated: false)
navigationController?.navigationBar.prefersLargeTitles = false
I tried to find a proper way to hide search bar, but I didn't find. But I found a workaround to hide your search bar which is change content offset your table view.
You may try this function to hide your table view and search bar.
func hide() {
tableView.isHidden = true
let point = tableView.contentOffset
let searchBarFrame = self.navigationItem.searchController?.searchBar.frame
let newPoint = CGPoint(x: point.x, y: point.y + searchBarFrame!.height)
tableView.setContentOffset(newPoint, animated: true)
}
Just try this:
navigationItem.searchController = nil
This is all my test code:
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var leftBarButtonItem: UIBarButtonItem!
var isHidden = false
var searchController: UISearchController {
let search = UISearchController(searchResultsController: nil)
search.searchBar.placeholder = "hello world"
search.obscuresBackgroundDuringPresentation = false
return search
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Test"
tableView.delegate = self
tableView.dataSource = self
showSearchController()
}
#IBAction func isHiddenAction(_ sender: UIBarButtonItem) {
isHidden = !isHidden
self.tableView.isHidden = isHidden
if isHidden {
leftBarButtonItem.title = "Show"
hiddenSearchController()
} else {
leftBarButtonItem.title = "Hidden"
showSearchController()
}
}
func hiddenSearchController() {
navigationItem.searchController = nil
}
func showSearchController() {
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true
definesPresentationContext = true
}
I have stumbled over sort of glitch. When I load this view first time, everything is okay:
If I go to the next view, my UINavigationBar looks like this:
If I press back now, I cant press the scopeButton which is displayed in the first image.
I know if I remove the UISearchBar(second image), I will be able to press the scopeButtons (first image).
This is my code for first image:
var searchBar = UISearchBar()
override func viewDidLoad() {
secondContainerView.isHidden = true
searchBar.delegate = self
searchBar.placeholder = "Search"
searchBar.scopeButtonTitles = ["0", "1"]
searchBar.tintColor = UIColor.white
searchBar.barTintColor = UIColor(red: 105/255, green: 185/255,
blue: 114/255, alpha: 1.00)
navigationItem.titleView = searchBar
}
This is my code for the second image:
var searchBar = UISearchBar()
override func viewDidLoad() {
searchBar.delegate = self
searchBar.placeholder = "Search"
navigationItem.titleView = searchBar
}
I figured out that if I do this it works:
override func viewWillDisappear(_ animated: Bool) {
searchBar.removeFromSuperview()
}
Sadly this creates another problem, when I do the swipeGesture to go back, and stay on the current view, the UISearchBar is gone.
Edit:
If I tap the back button the scopItems won't respond, but on swipe, it works:
override func viewWillAppear(_ animated: Bool) {
navigationItem.titleView = searchBar
}
override func viewWillDisappear(_ animated: Bool) {
navigationItem.titleView = nil
}
override func viewDidAppear(_ animated: Bool) {
navigationItem.titleView = searchBar
}
I have a TabBar in my project and when user select item this item will disable but the color will change too! I want the color is same as other items color in TabBar
I used
item.isEnabled = false
for disable item but this codes here won't work for this item
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBar.barTintColor = UIColor.init(red: 126/255, green: 0/255, blue: 64/255, alpha: 1.0)
if #available(iOS 10.0, *) {
self.tabBar.unselectedItemTintColor = UIColor.white
self.tabBar.unselectedItemTintColor = UIColor.white
} else {
// Fallback on earlier versions
}
UITabBar.appearance().tintColor = UIColor.white
}
Try this code -
UITabBar.appearance().tintColor = UIColor.gray
UITabBar.appearance().unselectedItemTintColor = UIColor.gray
Hope this helps!
you can use the UITabBarControllerDelegate method in order to disable the selection
try this code
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
return false
}
I'm having a weird problem, when my app first loads you cannot enter text in the search bar no matter how many times you tap it, the search bar is nested in the navigation bar.
My app also use a tab bar, and when you switch tabs then go back to the tab with the search bar it allows you enter text... any ideas what's causing this?
Heres the code for the searchBar:
func setupSearchBar(){
let locationSearchTable = storyboard!.instantiateViewController(withIdentifier: "LocationSearchTable") as! LocationSearchTableViewController
resultSearchController = UISearchController(searchResultsController: locationSearchTable)
resultSearchController?.searchResultsUpdater = locationSearchTable
searchBar = resultSearchController!.searchBar
searchBar.sizeToFit()
searchBar.placeholder = "Location"
searchBar.isTranslucent = true
searchBar.isUserInteractionEnabled = true
for subView in searchBar.subviews{
for subsubView in subView.subviews{
if let textField = subsubView as? UITextField{
var currentTextFieldBounds = textField.bounds
currentTextFieldBounds.size.height = 40.0
textField.bounds = currentTextFieldBounds
textField.borderStyle = UITextBorderStyle.none
textField.textAlignment = NSTextAlignment.left
textField.font = UIFont(name: "System", size: 25.0)
textField.textColor = theme?.textColour
}
}
}
self.navigationController?.navigationBar.setBarColour(colour: (theme?.tabBarColour)!, tint: (theme?.textColour)!)
navigationItem.titleView = resultSearchController?.searchBar
navigationItem.titleView?.bringSubview(toFront: (resultSearchController?.searchBar)!)
searchBar.delegate = self
searchBar.showsSearchResultsButton = true
searchBar.setImage(#imageLiteral(resourceName: "location_icon.png"), for: UISearchBarIcon.resultsList, state: UIControlState.normal)
resultSearchController?.hidesNavigationBarDuringPresentation = false
resultSearchController?.dimsBackgroundDuringPresentation = true
definesPresentationContext = true
locationSearchTable.mapView = mapView
locationSearchTable.handleMapSearchDelegate = self
}
Ok after a lot messing around, I discovered that in my custom UITabBarController I had used override func viewWillAppear(_ animated: Bool) without adding super.viewWillAppear() and that caused the problem! I assume because of that subviews weren't being laid out correctly. Hope that helps anyone who has a similar problem to mine.