A custom search controller that allow adding additional buttons to search bar, just like App Store on iPad.
I don't think I need to make a framework just for this, so this is a single file "framework" for y'all.
Just drag IXSearchController.swift to your project, no need to import.
Using IXSearchController is just like using UISearchController:
let searchController = IXSearchController(searchResultsController: nil)
navigationItem.searchController = searchControllerYou can add buttons to the left or right side of the search bar using leftBarItemsStack or rightBarItemsStack. It's as easy as adding view to a stack view:
let filterButton = UIButton(type: .system)
filterButton.setTitle("Filter", for: .normal)
filterButton.titleLabel?.font = UIFont.systemFont(ofSize: UIFont.buttonFontSize)
filterButton.setContentCompressionResistancePriority(.required, for: .horizontal)
searchController.leftBarItemsStack.addArrangedSubview(filterButton)By default, a cancel button is inserted right-most to rightBarItemsStack. You can disable this behavior by setting:
searchController.autoInsertCancelButton = falseFor those buttons you added to the stack view, it's your responsibility to set its content compression resistance priority.
For god's sake, you should avoid adding too mach buttons to the search bar.
You can set a maximum width for the search bar:
searchController.maxSearchBarWidthWhenActive = 400The search bar will be display horizontally centered.
In addition to this, you can add extra spacing arround bar items stack:
searchController.extraBarItemSpacing = 30-
Layout and animation glitch when activating search bar for the first time.
When
hidesNavigationBarDuringPresentationis set totrue, there will be a layout glitch when activating search bar for the first time. This may because apple lazy-loaded search controller and use some custom view for visual before activating it.I didn't find a way to fix this yet, any pull request is welcome. But there's a temporary fix.
First, set
skipFirstTwoTransitiontotrue, so it will animate first two transitions in very short duration:searchController.skipFirstTwoTransition = true
Then, manually activate and deactivate search bar to force it to load:
override func viewDidAppear(_ animated: Bool) { searchController.isActive = true searchController.isActive = false }
-
Layout glitches when hiding search bar by scrolling.
When
hidesSearchBarWhenScrollingis set totrue, there's a little glitch when navigation bar shrink after a transition happened.
