How to hide iOS keyboard when side menu opens? - ios

I am using SWRevealViewController for side menu and IQKeyboardManagerSwift for keyboard.
When I am editing content in textfield and tries to open menu, the keyboard should automatically hide but I can't manage to do so.
How should this be done?

Capture the event of the opening menu. You can do this with SWRevealViewcontroller Delegate or by simply adding an #IBAction to the menu button.
In this method call .resignFirstResponder() for the element that needs the keyboard (like a textField):
textField.resignFirstResponder()
Of course you can call this function in every element that can have a keyboard to be sure to call the right one.

Since UIBarButtonItem doesn’t inherit from UIView or expose the item’s underlying view, this isn’t as easy as adding a gesture recognizer.
One plausible solution would be to [Step 1] define a custom view for the Side Menu Icon [Step 2]add the gesture to hide keyboard to it.
//gesture:tap anywehere to dismiss the keyboard
let tap = UITapGestureRecognizer(target:self.view,action:#selector(UIView.endEditing))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
let customButton = UIButton(frame: CGRect.init(x: 0, y: 0, width: 20, height: 20))
customButton.setImage(UIImage(named: "menu"), for: .normal)
//hide keyboard gesture(tap gesture)
customButton.addGestureRecognizer(tap)
customButton.isUserInteractionEnabled = true
if self.revealViewController() != nil {
customButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
self.navigationItem.leftBarButtonItem?.customView = customButton
Please accept as answer if it works.(Worked for me)

Related

Causing cancel button and software keyboard to appear automatically in viewDidLoad()

Note: I have attempted using .becomeFirstResponder() as shown in the link above. I stupidly left that detail out in my first post. See my code for edits.
I'm using a UISearchBar in it's own dedicated viewController (the code used for the search bar is from Google as part of their SDK). As soon as the app segues into that viewController, I want the keyboard to appear immediately without user intervention, and I don't want it to disappear. More importantly, I would like the cancel button to remain visible at all times.
I'm already aware of how to make the keyboard disappear using resignFirstResponder. I tried using .becomeFirstResponder() to no effect. However, looking on StackOverflow, out on Google, and in Apple's documentation, I'm not seeing a way to make it appear without user intervention.
All of the functions, such as editingDidBegin() require the user to do something.
This feels pretty basic, but I'm coming up empty.
private var resultsViewController: GMSAutocompleteResultsViewController?
private var searchController: UISearchController?
private var resultView: UITextView?
// tableview code for Google autocomplete
private var tableDataSource: GMSAutocompleteTableDataSource?
// not including irrelevant code...
// called in viewDidLoad()
func displaySearchBar(){
let searchVerticalLocation = UIScreen.main.bounds.height-UIScreen.main.bounds.height+33
resultsViewController = GMSAutocompleteResultsViewController()
resultsViewController?.delegate = self
//resultsViewController.becomeFirstResponder() doesn't work
searchController = UISearchController(searchResultsController: resultsViewController)
searchController?.searchResultsUpdater = resultsViewController
let subView = UIView(frame: CGRect(x: 0, y: searchVerticalLocation, width: 350, height: 60))
searchController?.searchBar.barTintColor = UIColor(red: 234/255.0, green: 93/255.0, blue: 0/255.0, alpha: 1.0)
searchController?.searchBar.keyboardAppearance = .dark
searchController?.searchBar.searchBarStyle = .prominent
searchController?.searchBar.placeholder = "enter destination"
searchController?.searchBar.isTranslucent = true
searchController?.searchBar.leftAnchor.constraint(equalTo: subView.leftAnchor, constant: 100)
searchController?.searchBar.rightAnchor.constraint(equalTo: subView.rightAnchor, constant: -100)
searchController?.searchBar.delegate = self
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): UIColor.white], for: .normal)
//Everything with this tap recognizer is an attempt to ensure that the cancel button on the searchbar doesn't disappear.
let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.cancelSearchBar(sender:)))
singleTapGestureRecognizer.delegate = self
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.isEnabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
searchController?.searchBar.addGestureRecognizer(singleTapGestureRecognizer)
subView.addSubview((searchController?.searchBar)!)
view.insertSubview(subView, at: 1)
// When UISearchController presents the results view, present it in
// this view controller, not one further up the chain.
definesPresentationContext = true
searchController?.isActive = true
searchController?.searchBar.becomeFirstResponder()
//searchController?.becomeFirstResponder() doesn't work either
}
// this code brings back the cancel button if the user taps in the searchbar's text field. It's an imperfect solution. I'd rather have it so that the searchbar doesn't disappear at all. Not sure how to make that happen yet.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
searchController?.isActive = true
return true
}
The keyboard and cancel button currently only appear when the user taps inside the text field. Tapping anywhere else on the screen causes them to disappear.
For the cancel button, you can make it appear automatically using searchBar.showsCancelButton = true. However, this will not respond to touches until the keyboard appears.
Calling .becomeFirstResponder on the searchBar will only work after the searchController is finished loading. Please reference the following article: Cannot set searchBar as firstResponder.
Calling searchBar.becomeFirstResponder() in viewDidAppear(), and even forcing it onto the main thread using DispatchQueue.main.async{} (as some people suggest) did not work. The following code snippet, called from viewDidLoad(), is my current working solution:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(700), execute: {
self.searchController?.searchBar.becomeFirstResponder()
})
I may adjust the delay to make it longer, to ensure that it works on all devices. This works on an iPhoneXR.

How to set focus to next TextField in view by hitting button?

There was many guys who meet problem with absence of Done button in numeric keyboard for iOS and there are many solutions to do it. I create this button but I cant find way to set focus on next text field by hit on this button. In my case there code that generates Table with TableViewCells. Thats why common idea to create reference to every Cell (anyway there are many cells). Every TableViewCell include ContentView and ContentView include TextField.
As result my custom Done button should behave like Return button in standard keyboard. By the way there method in textFieldShouldReturn that change focus but textFieldShouldReturn invoked on built-in Return button.
P.S. Im new in Swift.
Note: I have created a sample project where the next button functionality is implemented. You can find the project: https://github.com/nasirky/uitableview-form
You can add a toolbar with a done button to the UITextField inputAccessoryView. Here is an example
override func viewDidLoad() {
super.viewDidLoad()
textField.inputAccessoryView = getToolbar()
}
func getToolbar() -> UIToolbar {
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 40))
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action:#selector(doneAction(_:)))
toolBar.setItems([doneButton], animated: false)
return toolBar
}
func doneAction(_ sender: UIBarButtonItem) {
/* Code for dismissing keyboard or moving focus to next UITextField */
}
After I carefully rechecked existing jump function I put it into textFieldDidEndEditing event. Inside Done function (doneAction in Nasir`s example) I put self.endEditing(true)

iOS/Swift: How to implement doubletap action for backButton? [duplicate]

This question already has answers here:
on single tap UIBarButton display toast and on double tap back action need to perform
(3 answers)
Closed 4 years ago.
I'm trying to implement a custom back button for every ViewController in my app. I want it to have two actions. If the button gets single tapped, it should give toast warning. If the button gets double tapped it should go back to ViewController.
How can I achieve this for only the backbutton in swift?
Try this to Work with bar Button with single and Double Tap
/// Tap Gesture to Handle Double Tap
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(SourceVC.handleGesture(getsure:)))
tapGesture.numberOfTapsRequired = 2
/// Custom Button That With Handle two actions
let customButtonn : UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
customButtonn.setTitleColor(UIColor.blue, for: .normal)
customButtonn.setTitle("button", for: .normal)
customButtonn.addTarget(self, action: #selector(SourceVC.navButton(sender:)), for: .touchUpInside)
customButtonn.addGestureRecognizer(tapGesture)
/// Create a Custom bar Button
let navLeftButton = UIBarButtonItem()
navLeftButton.customView = customButtonn
/// Assign it to navigation Bar
self.navigationItem.leftBarButtonItem = navLeftButton
My custom Button Actions in SourceVC Class
/// Single Tap
#objc func navButton(sender:UIButton){
print("navButtonTapped Once")
}
/// Double Tap
#objc func handleGesture(getsure:UITapGestureRecognizer){
print("navButtonTapped twice")
}
Simulator Output:
Console output:
Note - Doing this will move default back occur with the bar and you need to design it custom way so it appear like that as Shown in Simulator output - button appear without that back image
You cannot modify the actions and behavior for BackBarButtonItem, what you can do is create a your own UIBarButtonObject and assign it as your leftBarButtonItem while giving it your own selector
One thing to note is that this will remove the stock back button image.
Try this:
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(actingFunction))
DoubleTap.numberOfTapsRequired = 2
barButton.addGestureRecognizer(doubleTap)

Custom keyboard that mimics the default iOS "globe" button

In iOS keyboards there is a globe button that if held will show a pop-up list of keyboards that the user can switch to.
However in the KeyboardViewController class, the only method I see to make a keyboard switch button is the method:
self.advanceToNextInputMode()
The problem with this is that while it allows you to create a button that if clicked will switch keyboards this method does not allow you to create a button that if you press and hold will show the list of currently enabled keyboards that the user can switch to by moving their finger to the correct entry.
How can I mimic the default iOS globe keyboard button behavior?
// Launch inputMode list above the view when long pressing or swiping up from the view,
// Advance to nextInputMode when short tapping on the view.
// Example:
[KeyboardButton addTarget:self action:#selector(handleInputModeListFromView:withEvent:) forControlEvents:UIControlEventAllTouchEvents].
(void)handleInputModeListFromView:(nonnull UIView *)view withEvent:(nonnull UIEvent *)event NS_AVAILABLE_IOS(10_0);
Swift Code
override func viewDidLoad() {
super.viewDidLoad()
// Perform custom UI setup here
self.nextKeyboardButton = UIButton(type: .system)
self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), for: [])
self.nextKeyboardButton.sizeToFit()
self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)
self.view.addSubview(self.nextKeyboardButton)
self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
}

Insert a button and load a second view programmatically using Swift

I want to, programmatically, add a button to a view and then when the user press this button a second view called "Giraanam" is loaded. I managed to write the code to display the button, but I cannot discover how to make it load the second view... Can anyone please help me?
The code I tried so far is:
let button = UIButton.buttonWithType(UIButtonType.System) as UIButton
button.frame = CGRectMake(20, 25, 34, 34)
button.backgroundColor = UIColor.greenColor()
button.setBackgroundImage(UIImage(named:"Back_Resultados.png"),forState: UIControlState.Normal)
button.addTarget(self, action: "Giraanam", forControlEvents: UIControlEvents.TouchUpInside)
self.addSubview(button)
You need to implement function Giraanam to create a new view and add to another view. Example:
func Giraanam() {
let newView = UIView()
// customise your view
self.view.addSubview(newView)
}

Resources