In the iOS calendar app, when you press the search icon, an animated dropdown containing a search bar is shown, and it instantly gains focus.
Before Pressing The Search Icon
After Pressing The Search Icon
How would I go about developing a similar search dropdown in my onw app? What sort of classes / methods would I use to achieve this and how would they be put together? Note, I'm sure I could find a third party library to handle this, but I want to know how the could be done using only core iOS libraries.
lazy var searchBar = UISearchBar(frame: CGRectMake(0, 0, 0, 0))
override func viewDidLoad() {
super.viewDidLoad()
searchBar.placeholder = "Search"
self.navigationItem.rightBarButtonItem.image = UIImage(named: searchIcon.png)
}
func searchIconTapped() {
navigationItem.titleView = searchBar
}
To go back to default, just set the navigationItem.titleView back to nil
Related
I have a UINavigationBar which contains 3 parts:
titleView (which is UISearchBar)
leftBarButtonItems
rightBarButtonItems
when the voice-over is on, the search bar will be the first one to be focused.
which is not confirmed to the left to right order we are familiar with.
I tried to set UINavigationItem's accessibilityElements, but it still will highlight the searchBar first. assume because, inside the UINavigationItem, the titleView is the first subView.
any ideas on how to change the order, thanks~
Any ideas on how to change the order?
I assume your problem deals with the way you added the search bar in the navigation bar.
I created a blank project as follows:
The code snippet hereafter is an example of adding a search bar as the title view: 🤓
class SearchViewController: UIViewController, UISearchBarDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let search = UISearchBar()
search.showsCancelButton = true
search.delegate = self
self.navigationItem.titleView = search
}
}
The result with VoiceOver on gives rise to the following screenshots:
Following this rationale, you have the VoiceOver initial reading order from left to right in the navigation bar. 🥳🎊🎉
I suggest to take a look at this site if further information is needed about a11y in the navigation bar and especially if you want to make a specific reading order. 👍
In iOS 13, search bars in all Apple apps have a mic icon on the right that allows for voice input. However, when I create a system search bar (or UISearchController), I don't get the mic icon. I've searched on Google and SO and couldn't find the answer - is it something we can adopt, and if so how?
One important note is that currently there is not a way to programmatically put the user into "Dictation mode". This means to implement this, your must use the Speech framework in order to get "speech-to-text" working from a button press.
You can accomplish the visual styling by updating the image for the search bar's bookmark icon and setting showsBookmarkButton on the search bar to true.
Here is an implementation with a UISearchController:
let searchController = UISearchController(searchResultsController: nil)
let micImage = UIImage(systemName: "mic.fill")
searchController.searchBar.setImage(micImage, for: .bookmark, state: .normal)
searchController.searchBar.showsBookmarkButton = true
You handle the button tap via the search bar's delegate:
searchController.searchBar.delegate = self
func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {
// Do work here
}
I have a customized UISearchController with a custom UISearchBar as the title of a navigation controller, so that there's a persistent search bar control visible throughout the changes of child view controllers, which is shown in the first image of my gallery (not enough reputation to post images yet):
http://imgur.com/a/IikEw
However, when a user taps a search result displayed in a child table view controller, the navigation title is replaced with a text string, so that it looks like the second image in my gallery.
The problem occurs when I navigate back to the table view showing the search results, because for a brief moment, the search bar has a light gray background that looks like the third image in my gallery.
And when I slow down the animations in the simulator, I'm able to enter the Debug View Hierarchy in Xcode to see what the offending element is, which turns out to be a UIImageView named "UISearchBarBackground" that exists only until the transition animation ends, and the color snaps back to the intended result, as shown in the fourth image in my gallery.
In the initial view controller that initializes and sets the properties of my UISearchController, I've set the following properties of the search bar in viewDidLoad:
let controller = CustomSearchController(searchResultsController: self.searchResultsController)
controller.searchBar.backgroundColor = UIColor.clear
controller.searchBar.backgroundImage = nil
...and I have these custom classes, which I implemented so that I could get rid of the search controller's cancel button, which won't stay removed with delegate statements:
class CustomSearchBar: UISearchBar {
override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) {
super.setShowsCancelButton(false, animated: false)
}
}
class CustomSearchController: UISearchController {
lazy var _searchBar: CustomSearchBar = {
[unowned self] in
let customSearchBar = CustomSearchBar(frame: CGRect.zero)
return customSearchBar
}()
override var searchBar: UISearchBar {
get {
return _searchBar
}
}
}
As far as I can understand, at no point is my custom search controller deinitialized, and it is only initialized once, so I feel like the problem is appearing because of the drawing cycle, which temporarily places a visible view with a gray background before my settings take effect.
I'm pretty much at a loss as to what exactly is going on here, and how to solve this issue. I'm wondering if I'm just overlooking something simple, or if I instead have to create a custom transition object to solve the problem. I'm about an intermediate level with iOS architecture and Swift, but am always looking to learn more.
I've figured out that this issue is caused by not having a value set to the optional barTintColor property of UISearchBar. If the property is nil during a transition animation, then the view will appear light gray until the animation ends. To solve the problem, I set controller.searchBar.barTintColor = UIColor(red: 76/255, green: 203/255, blue: 124/255, alpha: 1), and now I'm getting the intended results.
Looking to create a floating menu in Swift for an iOS application I am developing. Something along the lines of the little red circle menu as shown in the following image.
My initial thoughts were to extend the UIViewController class and add the respective drawing/logic there, however, the application is comprised of a few other controllers, more specifically the UITableViewController which in itself extends UIViewController. Is there perhaps a good place for an extension perhaps? Or is there a more eloquent way of drawing the menu on specific views without the mass duplication of menu related code?
The menu itself will be shown on most screens, so I need to selectively enable it. It'll also be somewhat contextual based on the view/screen the user is currently on.
Any awesome ideas?
You can create your own with the animations and all the things, or you can check this library
https://github.com/lourenco-marinho/ActionButton
var actionButton: ActionButton!
override func viewDidLoad() {
super.viewDidLoad()
let twitterImage = UIImage(named: "twitter_icon.png")!
let plusImage = UIImage(named: "googleplus_icon.png")!
let twitter = ActionButtonItem(title: "Twitter", image: twitterImage)
twitter.action = { item in println("Twitter...") }
let google = ActionButtonItem(title: "Google Plus", image: plusImage)
google.action = { item in println("Google Plus...") }
actionButton = ActionButton(attachedToView: self.view, items: [twitter, google])
actionButton.action = { button in button.toggleMenu() }
}
There is another alternative with this great library :
https://github.com/yoavlt/LiquidFloatingActionButton
You just have to implement the delegate and the dataSource in your ViewController:
let floatingActionButton = LiquidFloatingActionButton(frame: floatingFrame)
floatingActionButton.dataSource = self
floatingActionButton.delegate = self
You could use view controller containment. The menu can be its own view controller with its view laid transparently over top the content view controller.
For example this can be set up in the storyboard by dragging out two container views into a vanilla view controller.
I'm quite new to Xcode. I'm building a basic app that searches a website. Ive got the search button to work with a Go button at the side. How would i make the search button also respond to the search on the bottom right on the keyboard?
#IBAction func didClickGo(AnyObject) {
var text = textField.text
var url = NSURL.URLWithString("http://www.mysite.co.uk/search?controller=search&orderby=position&orderway=desc&search_query="+text)
var request = NSURLRequest(URL: url)
webView.loadRequest(request)
Check out this answer:
https://stackoverflow.com/a/22178145/4014757
First, in your view controller you can assign a delegate for the search bar (probably also your view controller)
searchBar.delegate = this;
Then in your view controller (the delegate), you can override the searchBarSearchButtonClicked method with whatever you want to do when the search button is pressed.
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Hope this is what you're looking for, good luck.