How to dismiss suggestions at top of keyboard? [duplicate] - ios

Is there any way to hide suggestions list above keyboard? I couldn't find any solution in documentation.

Yes there is. You have to disable autocorrection on the text field/text/any other class that conforms to the UITextInputTraits protocol, which can be done through the autocorrectionType property.
textField.autocorrectionType = .no
Additionally, if you're interested, the following are the only UIKeyboardTypes
that don't have suggestions by default.
DecimalPad
NumberPad
PhonePad

Swift 4.0 +:
textfield.autocorrectionType = .no
To hide the bar (predictive bar), use this code:
if #available(iOS 9.0, *) {
var item = textField.inputAssistantItem
item.leadingBarButtonGroups = [];
item.trailingBarButtonGroups = [];
}
For disabling copy-and-paste, use this function:
override func selectionRects(for range: UITextRange) -> [Any] {
return []
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
let menu = UIMenuController.shared
menu.isMenuVisible = false
return false
}

iOS 15 (maybe ealier)
The answers above did not work:
To remove the Suggestion list (predictive - spell checking)
Need to make:
textField.spellCheckingType = .no
That's what worked for me!

(Edited in June 2020: still true for Xcode 11.3.1)
In more recent versions of Xcode storyboards, you can also set the keyboard traits in the storyboard (right panel, the attributes inspector, then look for Text Input Traits and select the traits you want, at least in Xcode 9). In particular, select "No" for the Correction trait, as shown in the example below. Interestingly, this is for content type Username, and the Default selection for the Correction trait was to turn on Correction, unlike a content type like Password, for example.

As of August 19th, 2022 the following worked for me:
textField.spellCheckingType = .no
textField.autocorrectionType = .no
The other approaches did not work

Related

How to hide suggested email id from keyboard in swift

I want to hide email suggestion which is displaying while i choose email textField in my application.
I have tried different options like below but none of them works for me.
txtEmail.autocorrectionType = .no
txtEmail.accessibilityLabel = .none
txtEmail.textContentType = .none
Is there anything else a part from this which i missed out ?
You can set UITextField text content type to an empty string:
txtEmail.textContentType = .init(rawValue: "")
I don't know how, but #Leo Dabus answer doesn't work in my case, however, an approach below does
textView.autocorrectionType = .no
textView.keyboardType = .emailAddress
I had to set keyboardType not to .default.

how to change keyboard style programmatically in iOS?

I would like to change the keyboard style.
I have attached two pictures one the current situation and the second one is the desired situation.
try this to change the keyboard type:
self.someTextField.keyboardType = UIKeyboardType.decimalPad
and for number with special character try this :-
UIKeyboardType.numbersAndPunctuation
from :- https://developer.apple.com/documentation/uikit/uitextinputtraits#//apple_ref/c/tdef/UIKeyboardType
well thanks for suggetions and answers .
i found the solution for it.
for the numbers
textField.keyboardType = UIKeyboardType.numbersAndPunctuation
for the alphabets
textField.keyboardType = UIKeyboardType.emailAddress
- Keyboard Type Suggestions
textField.keyboardType = .emailAddress
After = . (Multiple Suggestions for keyboard type you can select according to your usage)

UITextView autocapitalization is not working when keyboard is active

Currently, I am setting autocapitalization in a button target like this
//This method is fired when keyboard is still active
- (IBAction)changeAutoCapitalization:(id)sender
{
self.textView.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
But this won't make keyboard to capital.
You have to call [self.textView reloadInputViews] after modifying the UITextAutocapitalizationType in order to change keyboard immediately.
If you find that you're doing a lot of text-related customizations, it might be helpful to subclass UITextView, to keep the functionality encapsulated.
Note: If testing on the simulator, make sure you are using the
Simulator's keyboard, by going to the menu: I/O -> Keyboard -> Toggle
Software Keyboard
If you are adding text automatically, for instance in response to a button tap, and the shift key turns off, then you can use this pattern:
autocapitalizationType = .allCharacters //Activate shift key
autocorrectionType = .no //Don't show all-caps auto suggest
reloadInputViews() //Apply changes
Then, to restore to sentences capitalization, for instance when a line is cleared:
if (autocapitalizationType = .allcharacters) {
autocapitalizationType = .sentences //Activate sentence capitalization
autocorrectionType = .yes //Show auto suggest
reloadInputViews() //Apply changes
}
Other capitalization options:
.none
.words
You may also need to do this when any non-enter key is pressed. To do so, override insertText from UIKeyInput, and check the entered text string:
if (text != "\n") {
if (autocapitalizationType == .allCharacters) {
autocapitalizationType = .sentences //Activate sentence capitalization
autocorrectionType = .yes //Show auto suggest
reloadInputViews() //Apply changes
}
//Respond to any character sequences
//...
}
Try to add this after initialization:
self.textView.autocapitalizationType = UITextAutocapitalizationTypeWords;
OR
It's very likely that the "Auto-Capitalization" option is turned off on that device. You can find that option in Settings > General > Keyboard.

How to hide keyboard in Swift app during UI testing

I just started with UI testing in Xcode 7 and hit this problem:
I need to enter text into a textfield and then click a button. Unfortunately this button is hidden behind the keyboard which appeared while entering text into the textfield. Xcode is trying to scroll to make it visible but my view isn't scrollable so it fails.
My current solution is this:
let textField = app.textFields["placeholder"]
textField.tap()
textField.typeText("my text")
app.childrenMatchingType(.Window).elementBoundByIndex(0).tap() // hide keyboard
app.buttons["hidden button"].tap()
I can do this because my ViewController is intercepting touches:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
view.endEditing(false)
super.touchesBegan(touches, withEvent: event)
}
I am not really happy about my solution, is there any other way how to hide the keyboard during UI testing?
If you have set up your text fields to resign FirstResponder (either via textField.resignFirstResponder() or self.view.endEditing(true)) in the textFieldShouldReturn() delegate method, then
textField.typeText("\n")
will do it.
Swift 5 helper function
func dismissKeyboardIfPresent() {
if app.keyboards.element(boundBy: 0).exists {
if UIDevice.current.userInterfaceIdiom == .pad {
app.keyboards.buttons["Hide keyboard"].tap()
} else {
app.toolbars.buttons["Done"].tap()
}
}
}
Based on a question to Joe's blog, I have an issue in which after a few runs on simulator the keyboards fails to hide using this piece of code:
XCUIApplication().keyboard.buttons["Hide keyboard"]
So, I changed it to: (thanks Joe)
XCUIApplication().keyboard.buttons["Hide keyboard"]
let firstKey = XCUIApplication().keys.elementBoundByIndex(0)
if firstKey.exists {
app.typeText("\n")
}
What I try to do here is detecting if the keyboard stills open after tap the hide button, if it is up, I type a "\n", which in my case closes the keyboard too.
This also happens to be tricky, because sometimes the simulator lost the focus of the keyboard typing and this might make the test fail, but in my experience the failure rate is lower than the other approaches I've taken.
I hope this can help.
I always use this to programmatically hide the keyboard in Swift UITesting:
XCUIApplication().keyboards.buttons["Hide keyboard"].tap()
XCUIApplication().toolbars.buttons["Done"].tap()
With Swift 4.2, you can accomplish this now with the following snippet:
let app = XCUIApplication()
if app.keys.element(boundBy: 0).exists {
app.typeText("\n")
}
The answer to your question lies not in your test code but in your app code. If a user cannot enter text using the on-screen software keyboard and then tap on the button, you should either make the test dismiss the keyboard (as a user would have to, in order to tap on the button) or make the view scrollable.
Just make sure that the keyboard is turned off in the simulator before running the tests.
Hardware->Keyboard->Connect Hardware Keyboard.
Then enter your text using the paste board
textField.tap()
UIPasteboard.generalPasteboard().string = "Some text"
textField.doubleTap()
app.menuItems["paste"].tap()
I prefer to search for multiple elements that are possibly visible to tap, or continue, or whatever you want to call it. And choose the right one.
class ElementTapHelper {
///Possible elements to search for.
var elements:[XCUIElement] = []
///Possible keyboard element.
var keyboardElement:XCUIElement?
init(elements:[XCUIElement], keyboardElement:XCUIElement? = nil) {
self.elements = elements
self.keyboardElement = keyboardElement
}
func tap() {
let keyboard = XCUIApplication().keyboards.firstMatch
if let key = keyboardElement, keyboard.exists {
let frame = keyboard.frame
if frame != CGRect.zero {
key.forceTap()
return
}
}
for el in elements {
if el.exists && el.isHittable {
el.forceTap()
return
}
}
}
}
extension XCUIElement {
///If the element isn't hittable, try and use coordinate instead.
func forceTap() {
if self.isHittable {
self.tap()
return
}
//if element isn't reporting hittable, grab it's coordinate and tap it.
coordinate(withNormalizedOffset: CGVector(dx:0, dy:0)).tap()
}
}
It works well for me. This is how I would usually use it:
let next1 = XCUIApplication().buttons["Next"]
let keyboardNext = XCUIApplication().keyboards.firstMatch.buttons["Next"]
ElementTapHelper(elements: [next1], keyboardElement: keyboardNext).tap()
Nice thing about this is you can provide multiple elements that could be tapped, and it searches for keyboard element first.
Another benefit of this is if you are testing on real devices the keyboard opens by default. So why not just press the keyboard button?
I only use this helper when there are multiple buttons that do the same thing, and some may be hidden etc.
If you are using IQKeyboardManager you can easily do this:
app.toolbars.buttons["Done"].tap()
This way you capture the "Done" button in the keyboard toolbar and hide the keyboard. It also works for different localizations.

iOS 8 - How to hide suggestion list above keyboard?

Is there any way to hide suggestions list above keyboard? I couldn't find any solution in documentation.
Yes there is. You have to disable autocorrection on the text field/text/any other class that conforms to the UITextInputTraits protocol, which can be done through the autocorrectionType property.
textField.autocorrectionType = .no
Additionally, if you're interested, the following are the only UIKeyboardTypes
that don't have suggestions by default.
DecimalPad
NumberPad
PhonePad
Swift 4.0 +:
textfield.autocorrectionType = .no
To hide the bar (predictive bar), use this code:
if #available(iOS 9.0, *) {
var item = textField.inputAssistantItem
item.leadingBarButtonGroups = [];
item.trailingBarButtonGroups = [];
}
For disabling copy-and-paste, use this function:
override func selectionRects(for range: UITextRange) -> [Any] {
return []
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
let menu = UIMenuController.shared
menu.isMenuVisible = false
return false
}
iOS 15 (maybe ealier)
The answers above did not work:
To remove the Suggestion list (predictive - spell checking)
Need to make:
textField.spellCheckingType = .no
That's what worked for me!
(Edited in June 2020: still true for Xcode 11.3.1)
In more recent versions of Xcode storyboards, you can also set the keyboard traits in the storyboard (right panel, the attributes inspector, then look for Text Input Traits and select the traits you want, at least in Xcode 9). In particular, select "No" for the Correction trait, as shown in the example below. Interestingly, this is for content type Username, and the Default selection for the Correction trait was to turn on Correction, unlike a content type like Password, for example.
As of August 19th, 2022 the following worked for me:
textField.spellCheckingType = .no
textField.autocorrectionType = .no
The other approaches did not work

Resources