UITextField for nickname - ios

I need to set UITextField for nickname. It need to be english only, lowercase, underscore and numbers. Really don't know how to do that and can't find any information. Thanks for your time!

you can create a regex for this & comparison textfield value with your regex pattern.
func isValidName(name:String)-> Bool {
let nameRegEx = "^[a-z0-9_]+$" // this mean you can only use lower case a-z, 0-9 and underscore
let namelTest = NSPredicate(format:"SELF MATCHES %#", nameRegEx)
return namelTest.evaluate(with: name)
}
use this method and vaidate textfield value by pasting as parameter function.
if return true it means username passed validation.
if return false you can show an error to user or shake textfiled and set red color for textfield.text or placeholder color or any thing you want.
hope to this help you.

Related

Check UITextField while editing for different regex

I would like to check my passwordTextField while editing. I have three different criteria:
at least 8 characteres
at least 1 upper and lowercase letter
at least 1 digit
I already have this function which I need afterwards for checking all three cases at once:
static func isPasswordValid(_ password : String) -> Bool {
let passwordTest = NSPredicate(format: "SELF MATCHES %#", "^(?=.*[A-Z]).(?=.*[0-9]).(?=.*[a-z]).{8,}$")
return passwordTest.evaluate(with: password)
}
But for now I need to check the different cases separately while editing my textField.
I basically need 3 different regex checks inside some sort of whileEditing method I am stuck here...
Is there an easy way to get this done?
Use the UITextField EventListner method, to check your conditions. You can also set the below in Nibs or Storyboards,
textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
This passwordTest.evaluate(with: password) returns a result of unknown predicate hit so you have to separate them to handle what you need e.x there may be 8 charaters but no digits between them

How do I assert that a text field is empty?

I have an empty text field on my UI, though it has a placeholder text (whose value is foo) set in the storyboard. In my UI test, I am trying to check that its text value starts out empty, but when I query it's value, it seems to be giving me the placeholder value instead:
func testTextFieldInitiallyEmpty {
let input = XCUIApplication().textFields["My Text Field"]
XCTAssertEqual(input.value as! String, "")
}
as the test fails with this message:
XCTAssertEqual failed: ("foo") is not equal to ("")
Of course, foo is the placeholder value, but it's not the text value of that text field. I would have expected that error message if I had written:
XCTAssertEqual(input.placeholderValue as! String, "")
input is a XCUIElement, which implements XCUIElementAttributes, so I don't see anything else that would do the trick here.
How do I check (assert) that the text field is empty?
Edit
After doing some further research and trying out the suggestions below for using the input's properties of accessibilityValue, label, and title, I have not found any solution that will give me the text field's text value when there is text, and an empty string when only the placeholder is visible.
This seems like either (a) a bug, or (b) a questionable design decision from the test framework to not provide that ability. At a minimum, the documentation for XCUIElementAttributes#value seems inadequate to me, as the only detail is:
The exact type of value varies based on the type of the element.
Still looking for a better solution...
You can compare to the XCUIElementAttributes's placeholderValue variable in addition to checking for a blank string
extension XCUIElement {
func noTextEntered() -> Bool {
return self.value as? String != "" && self.value as? String != placeholderValue
}
}
Then you can run XCAssert(input.noTextEntered(), "Unexpected text entered into field")
Just make sure your placeholder is not something a user would type in. This way you don't have to hardcode placeholder values to check against
Kind of ridiculous that this is actually the case it works and that it needs a workaround.
Anyway, my solution to get the value w/o the placeholder interfering, based on #Jason's answer.
extension XCUIElement {
var valueWithoutPlaceholder: String {
if let v = value as? String, v != placeholderValue {
return v
}
return ""
}
}
Be aware, if the input is actually the placeholder this would break!
Try using accessibilityValue property of input.
func testTextFieldInitiallyEmpty {
let input = XCUIApplication().textFields["My Text Field"]
XCTAssertEqual(input.accessibilityValue, "")
}
If you command+click the property, you can see the following..
/*
Returns a localized string that represents the value of the element, such as the value
of a slider or the text in a text field. Use only when the label of the element
differs from a value. For example: A volume slider has a label of "Volume", but a value of "60%".
default == nil
default on UIKit controls == values for appropriate controls
Setting the property will change the value that is returned to the accessibility client.
*/
public var accessibilityValue: String?

Get string of all possible characters given iOS keyboard language

I'm trying to verify that every character in a text box is limited to the language's keyboard options. This means that in English, you would only be able to type characters which are accessible through the iOS keyboard. If there is a string containing all characters, or a code solution - either will work.
Thanks for the help.
Try something like this. Let me know if it helped :) Good luck!
let letters = CharacterSet.letters
let text = textField.text
let range = text.rangeOfCharacters(from: letters)
if range != nil {
// Yay it's correct
}else{
// Oh no
}
The CharacterSet documentation has multiple options for the characters you want to restrict the field to. You can even make your own character sets! Check out the link: https://developer.apple.com/documentation/foundation/characterset
You could check it like that (is Swift):
let charactersSet = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
if yourString.rangeOfCharacter(from: charactersSet.inverted) != nil {
print("string contains special characters")
}
You can try some thing like:
NSString *inputString = #"abc0129yourcontent";
BOOL success = [inputString isMatchedByRegex:#"^[0-9a-zA-Z]+$"];
You can convert in Swift if required.

Swift - How can I force users to import only integer in UITextField?

Normally, in Text Field, users can enter a String, and even if the users entered a number, the program would automatically understand it as a string.
So, here is my problem. I want to make a program evaluating the speed of a motorcyclist.
I have a text field, a text view and a button START. What I want to do is to apply SWITCH - CASE in classifying the number that the users enter in the text field, and then I will print out my evaluations to the text view, such as "Slow", "Fast Enough" or "Dangerously Fast".
However before applying switch - case, I think that I have to force the users to only enter Integer numbers to the text field. And if they enter any alphabet letter, the text view will appear: "Wrong format! Please try again!"
I think that I have to do something with the statement if to solve the problem, but the truth is I've just started learning Swift, and couldnt think of any possible solutions. Please help me.
Thank you.
If you are using storyboard just select the TextField and change the Keyboard type to NumberPad. This will only allow integers to be entered. Then you could just turn it into a Int when you get back the input.
if let convertedSpeed = Int(textField.text) {
// Implement whatever you want
} else {
// Notify user of incorrect input
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
if textField == Number_Txt // your text filed name
{
var result = true
let prospectiveText = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
if string.characters.count > 0
{
let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789").invertedSet
let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
let resultingStringLengthIsLegal = prospectiveText.characters.count > 0
let scanner = NSScanner(string: prospectiveText)
let resultingTextIsNumeric = scanner.scanDecimal(nil) && scanner.atEnd
result = replacementStringIsLegal && resultingStringLengthIsLegal && resultingTextIsNumeric
}
return result
}
else
{
return true
}
}
You can solve it in two ways.
Convert the typed text to Integer value.
Int(textfield.text!)
This one is very simpler. Choose the keyboard type as Numeric/ Numbers and Punctuation pad. So that, user can type only the nos.
Hope it helps..
You can specify the keyboard type of a textfield in storyboard, under attributes inspector.
"Decimal" would be the way to go for you (assuming that possible input can be e.g. 180.5)
To move on, you still can check the input like this:
if (Int(textfield.text!) != nil ) {
//Valid number, do stuff
} else {
textfield.text = "Wrong format! Please try again!"
}
EDIT:
The ' != nil ' means the following:
The Initializer of Int is failable. That means if you pass a string which does not contain a valid number, it will return nil (null if you are coming from java/c#). But if the string does contain a valid number, it will return a valid Int, therefore its not nil. I hope this makes it clear to you ;)

Getting the First Letter of a String in Hebrew

In a UITableView, I'm listing a bunch of languages to be selected. And to put a section index view to the right like in Contacts app, I'm getting all first letters of languages in the list and then use it to generate the section index view.
It works almost perfect, Just I encountered with a problem in getting first letter of some strings in Hebrew. Here a screenshot from playground, one of the language name that I couldn't get the first letter:
Problem is, the first letter of the name of the language that has "ina" language code, isn't "א", it's an empty character; it's not a space, it's just an empty character. As you can see, it's actually 12 characters in total, but when I get count of it, it says 13 characters because there is an non-space empty character in index 0.
It works perfectly if I use "eng" or "ara" languages with putting these values in value: parameter. So maybe the problem is cause of system that returns a language name with an empty character in some cases, I don't know.
I tried some different methods of getting first letter, but any of it didn't work.
Here "א" isn't the first letter, it's the second letter. So I thought maybe I can find a simple hack with that, but I want to try solving it before trying workarounds.
Here is the code:
let locale = NSLocale(localeIdentifier: "he")
let languageName = locale.displayNameForKey(NSLocaleIdentifier, value: "ina")!
let firstLetter = first(languageName)!
println(countElements(languageName))
for character in languageName {
println(character)
}
You could use an NSCharacterSet.controlCharacterSet() to test each character. I can't figure out how to stay in Swift-native strings, but here's a function that uses NSString to return the first non-control character:
func firstNonControlCharacter(str: NSString) -> String? {
let controlChars = NSCharacterSet.controlCharacterSet()
for i in 0..<str.length {
if !controlChars.characterIsMember(str.characterAtIndex(i)) {
return str.substringWithRange(NSRange(location: i, length: 1))
}
}
return nil
}
let locale = NSLocale(localeIdentifier: "he")
let languageName = locale.displayNameForKey(NSLocaleIdentifier, value: "ina")!
let firstChar = firstNonControlCharacter(languageName) // Optional("א")

Resources