Check if Swift text field contains non-whitespace - swift

This is an extension, not a duplicate, of How to check if a text field is empty or not in swift
The given answer,
#IBAction func Button(sender: AnyObject) {
if textField1.text != "" {
// textfield 1
}
}
does not work for me, i.e., the if-loop is triggered even when nothing is entered in the text field. (I have modified it from the original because I'm looking to trigger the code only when the field contains text).
The second answer
#IBAction func Button(sender: AnyObject) {
if !textField1.text.isEmpty{
}
}
comes much closer, but it accepts strings like " " as not empty. I could build something myself, but is there a function that will check if a string contains something other than whitespace?

This answer was last revised for Swift 5.2 and iOS 13.5 SDK.
You can trim whitespace characters from your string and check if it's empty:
if !textField1.text.trimmingCharacters(in: .whitespaces).isEmpty {
// string contains non-whitespace characters
}
You can also use .whitespacesAndNewlines to remove newline characters too.

Below is the extension I wrote that works nicely, especially for those that come from a .NET background:
extension String {
func isEmptyOrWhitespace() -> Bool {
if(self.isEmpty) {
return true
}
return (self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) == "")
}
}

Swift 4.2
Extension for String is empty or whitespace
extension String {
func isEmptyOrWhitespace() -> Bool {
// Check empty string
if self.isEmpty {
return true
}
// Trim and check empty string
return (self.trimmingCharacters(in: .whitespaces) == "")
}
}
The original poster's code is checking text on a textfield which is optional. So he will need some code to check optional strings. So let's create a function to handle that too:
Extension for Optional String is nil, empty or whitespace
extension Optional where Wrapped == String {
func isEmptyOrWhitespace() -> Bool {
// Check nil
guard let this = self else { return true }
// Check empty string
if this.isEmpty {
return true
}
// Trim and check empty string
return (this.trimmingCharacters(in: .whitespaces) == "")
}
}

akashivskyy answer in Swift 3.0:
let whitespaceSet = CharacterSet.whitespaces
if !str.trimmingCharacters(in: whitespaceSet).isEmpty {
// string contains non-whitespace characters
}

extension StringProtocol where Index == String.Index {
var isEmptyField: Bool {
return trimmingCharacters(in: .whitespaces) == ""
}
}
if yourTextField.text.isEmptyField {
// Field is empty
} else {
// Field is NOT empty
}

Answer in swift 4:
extension String {
func isEmptyOrWhitespace() -> Bool {
if(self.isEmpty) {
return true
}
return (self.trimmingCharacters(in: NSCharacterSet.whitespaces) == "")
}
}

Answer in Swift 3.0
if stringValue.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty
{}

Answer in Swift 3.*, considers newlines, tabs
extension String {
var containsNonWhitespace: Bool {
return !self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
}
}

Answer with a picture in case you need a demo
// MY FUNCTIONS
private func checkMandatoryFields(){
//CHECK EMPTY OR SPACES ONLY FIELDS
if let type = typeOutle.text, let name = nameOutlet.text, let address = addressOutlet.text, type.trimmingCharacters(in: .whitespaces).isEmpty || name.trimmingCharacters(in: .whitespaces).isEmpty || address.trimmingCharacters(in: .whitespaces).isEmpty {
print("Mandatory fields are: ")
errorDisplay(error: "Mandatory fields are: Type, Name, Address.")
return
}
}

swift 4.2
#IBAction func checkSendButton(_ sender: UITextField) {
if((sender.text?.count)! > 0 && !(sender.text!.trimmingCharacters(in: .whitespaces)).isEmpty){
self.sendButton.isEnabled = true
}
else{
self.sendButton.isEnabled = false
}
}

Method
func trim() -> String {
return self.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
}
Use
if textField.text.trim().count == 0 {
// Do your stuff
}

Related

Swift: Why is this immutable?

Can you tell me why this code does not work?
I have several arrays of [AnyObject] that contain UILabels and UITextForm.
This func should take as parameter an array and make all the labels and the text form disabled. I've tried with map, but still i have the same problem, the compiler tells me that or the variable is a constant or that is immutable.
func disableSectionForm(formSection section: inout [AnyObject]) {
for i in 0...section.count {
if section[i] is UILabel || section[i] is UITextField {
section[i].isEnabled = false
}
}
}
There are many compile errors here
Issue #1 (this is just a suggestion)
inout is not needed here because you are not mutating the section array, you are mutating the objects inside it instead.
Issue #2
The inout should go before the param name (if you are using Swift 2.2)
Issue #3
You should use self when comparing with dynamicType
Issue #4
You can't write section[i].isEnabled = false because AnyObject has no member isEnabled so you should do a cast
Issue #5
You are accessing an index outside of your array so this
0...section.count
should become this
0..<section.count
Code Version #1
Now your code looks like this
func disableSectionForm(formSection section: [AnyObject]) {
for i in 0..<section.count {
if section[i].dynamicType == UILabel.self {
(section[i] as? UILabel)?.enabled = false
} else if section[i].dynamicType == UITextField.self {
(section[i] as? UITextField)?.enabled = false
}
}
}
Code Version #2
Since:
you can iterate your elements in a safer way
you should use conditional cast instead of dynamicType comparation
you can write in
Swift 2.2
func disableSectionForm(formSection section: [AnyObject]) {
section.forEach {
switch $0 {
case let label as UILabel: label.enabled = false
case let textField as UITextField: textField.enabled = false
default: break
}
}
}
Swift 3.0 (beta 6)
func disableSectionForm(formSection section: [Any]) {
section.forEach {
switch $0 {
case let label as UILabel: label.isEnabled = false
case let textField as UITextField: textField.isEnabled = false
default: break
}
}
}
Code Version #3
Let's define a protocol to represents classes with an enabled Bool property.
Swift 2.2
protocol HasEnabledProperty:class {
var enabled: Bool { get set }
}
Let's conform to it UILabel and UITextLabel
extension UILabel: HasEnabledProperty { }
extension UITextField: HasEnabledProperty { }
And finally...
func disableSectionForm(formSection section: [AnyObject]) {
section.flatMap { $0 as? HasEnabledProperty }.forEach { $0.enabled = false }
}
Swift 3.0 (beta 6)
protocol HasEnabledProperty:class {
var isEnabled: Bool { get set }
}
extension UILabel: HasEnabledProperty { }
extension UITextField: HasEnabledProperty { }
func disableSectionForm(formSection section: [Any]) {
section.flatMap { $0 as? HasEnabledProperty }.forEach { $0.isEnabled = false }
}
try to check if let block and use optionals
func disableSectionForm(formSection section: inout [AnyObject]) {
for i in 0...section.count {
if let label = section[i] as? UILabel {
label.isEnabled = false
}
if let textField = section[i] as? UITextFiled {
textField.isEnabled = false
}
}
}

Checking if textfields are empty Swift

I know there are tons of stack overflow pages out there that explain how to do this but everytime I take the code from here and put it in i get the same error and that error is value of "string?" has no member "text" Any ideas of a solid way that will work for checking if a textfield is empty in swift?
let userEmail = userEmailTextField.text;
// Check for empty fields
if (userEmail.text.isEmpty) {
// Display alert message
return;
}
This post is given a good answer (it's a pity it has no "accepted" mark). Use (self.field.text?.isEmpty ?? true).
Assume your textField is declared as:
#IBOutlet weak var textField: UITextField!
You can check its emptiness with:
if textField.text?.isEmpty ?? true {
print("textField is empty")
} else {
print("textField has some text")
}
To use the variables in your edited post:
let userEmail = userEmailTextField.text;
// Check for empty fields
if userEmail?.isEmpty ?? true {
// Display alert message
return;
}
or:
// Check for empty fields
if userEmailTextField.text?.isEmpty ?? true {
// Display alert message
return;
}
The text property is an optional. So it can contains a String or nil.
If you want to treat nil as an empty String then just write
let isEmpty = (textField.text ?? "").isEmpty
Alternatively you can also use:
Swift 3:
if (textField.text.characters.count > 0) {
print("text field not empty")
} else {
print("text field empty")
}
Swift 4.x and above:
if (textField.text.count > 0) {
print("text field not empty")
} else {
print("text field empty")
}
Give you an example picture and cover code.
#IBAction func save(_ sender: Any) {
print("Saving...")
//CHECK MANDATORY FIELDS
checkMandatoryFields()
}
private func checkMandatoryFields(){
//CHECK EMPTY FIELDS
if let type = typeOutle.text, let name = nameOutlet.text, let address = addressOutlet.text, type.isEmpty || name.isEmpty || address.isEmpty {
print("Mandatory fields are: ")
errorDisplay(error: "Mandatory fields are: Type, Name, Address.")
return
}
//CHECK SPACE ONLY FIELDS
}
Here's the correct answer for this.
textField.text = ""
if (textField.text.isEmpty) {
print("Ooops, it's empty")
}
It was this check that helped me since it was necessary for me to send a request to the API, and it was necessary to send nill instead of "" if the textField is without text.
textField.text!.count > 0 ? textField.text : nil
Alternatively, you can check this way (but this option did not fit me):
if textField.text != nil {
} else {
}

Checking if a string contains a text in a textfield

How can I check if a String (for example "apple") contains text that I typed in a UITextField (for example "p" or "pp").
If the String contains the UITextField's text, I want to print a message - for example: "apple contains pp".
You can achieve that like so
class youClass: NSObject {
var yourTextFieldName = UITextField()
func someMethod() {
var apple = "apple"
if apple.containsString(self.yourTextfieldName.text!) {
print("apple contains \(self.yourTextfieldName.text!)")
}
}
}
You could extend String:
extension String {
#discardableResult
func containsText(of textField: UITextField) -> Bool {
// Precondition
guard let text = textField.text else { return false }
let isContained = self.contains(text)
if isContained { print("\(self) contains \(text)") }
return isContained
}
}
Instead of just printing a result, it also returns a Bool indicating whether or not the textField's text was contained in the String. The #discardableResult attribute allows you to ignore the return value if you want to though, without generating a compiler warning.
You could also take a reversed approach, by extending UITextField:
extension UITextField {
#discardableResult
func textIsContained(in target: String) -> Bool {
// Precondition
guard let text = self.text else { return false }
let isContained = target.contains(text)
if isContained { print("\(target) contains \(text)") }
return isContained
}
}
You would use these methods as follows:
// Your `UITextField`
let textField = UITextField()
textField.text = "pp"
// String extension:
"apple".containsText(of: textField) // returns `true` and prints "apple contains pp"
// UITextField extension:
textField.textIsContained(in: "apple") // returns `true` and prints "apple contains pp"

Prevent special characters in UITextField

How can I prevent the user from entering special characters in UITextField?
I solved the problem using this code:
let validString = NSCharacterSet(charactersInString: " !##$%^&*()_+{}[]|\"<>,.~`/:;?-=\\¥'£•¢")
// restrict special char in test field
if (textField == self.txt_firstName || textField == self.txt_lastName)
{
if let range = string.rangeOfCharacterFromSet(validString)
{
print(range)
return false
}
else
{
}
}
Swift 4.2
for emoji and special character
override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.isFirstResponder {
let validString = CharacterSet(charactersIn: " !##$%^&*()_+{}[]|\"<>,.~`/:;?-=\\¥'£•¢")
if (textField.textInputMode?.primaryLanguage == "emoji") || textField.textInputMode?.primaryLanguage == nil {
return false
}
if let range = string.rangeOfCharacter(from: validString)
{
print(range)
return false
}
}
return true
}
One more answer with default CharacterSet
Restrict all Special characters and also, this will support if any string you dont want to restrict.
extension String {
var containsValidCharacter: Bool {
guard self != "" else { return true }
let noNeedToRestrict = CharacterSet(charactersIn: " _") // NOT RESTRICT "Underscore and Space"
if noNeedToRestrict.containsUnicodeScalars(of: self.last!) {
return true
} else {
return CharacterSet.alphanumerics.containsUnicodeScalars(of: self.last!)
}
}
}
extension CharacterSet {
func containsUnicodeScalars(of character: Character) -> Bool {
return character.unicodeScalars.allSatisfy(contains(_:))
}
}
Usage:
extension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return string.containsValidCharacter
}
}
Here's an example of how you can allow users to only type alphanumeric characters using RxSwift.
Add the RxSwift pod
pod 'RxSwift', '~> 5'
Create a String extension to remove characters in a set
extension String {
func removeChars(in set: CharacterSet) -> String {
let filtered = self.unicodeScalars.filter { (scalarElement) -> Bool in
if (set.contains(scalarElement)) {
return false
}
return true
}
let trimmed = String(filtered.map({ (scalar) -> Character in
return Character(scalar)
}))
return trimmed
}
}
Use the RxSwift extension to remove invalid chars when the text changes
import UIKit
import RxSwift
class MyViewController: UIViewController {
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
setUpView()
}
private func setUpView() {
//Do view set up stuff here
//Use the extension here to listen to text changes and remove chars
myTextField.rx.text
.asDriver(onErrorJustReturn: "")
.drive(onNext: { [weak self] (text: String?) in
//Here you would change the character set to what you need
let newText = text?.removeChars(in: CharacterSet.alphanumerics.inverted)
self?.myTextField.text = newText
})
.disposed(by: disposeBag)
}
}
try with this
self.DataTblView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)

How to check if a text field is empty or not in swift

I am working on the code below to check the textField1 and textField2 text fields whether there is any input in them or not.
The IF statement is not doing anything when I press the button.
#IBOutlet var textField1 : UITextField = UITextField()
#IBOutlet var textField2 : UITextField = UITextField()
#IBAction func Button(sender : AnyObject)
{
if textField1 == "" || textField2 == ""
{
//then do something
}
}
Simply comparing the textfield object to the empty string "" is not the right way to go about this. You have to compare the textfield's text property, as it is a compatible type and holds the information you are looking for.
#IBAction func Button(sender: AnyObject) {
if textField1.text == "" || textField2.text == "" {
// either textfield 1 or 2's text is empty
}
}
Swift 2.0:
Guard:
guard let text = descriptionLabel.text where !text.isEmpty else {
return
}
text.characters.count //do something if it's not empty
if:
if let text = descriptionLabel.text where !text.isEmpty
{
//do something if it's not empty
text.characters.count
}
Swift 3.0:
Guard:
guard let text = descriptionLabel.text, !text.isEmpty else {
return
}
text.characters.count //do something if it's not empty
if:
if let text = descriptionLabel.text, !text.isEmpty
{
//do something if it's not empty
text.characters.count
}
Better and more beautiful use
#IBAction func Button(sender: AnyObject) {
if textField1.text.isEmpty || textField2.text.isEmpty {
}
}
another way to check in realtime textField source :
#IBOutlet var textField1 : UITextField = UITextField()
override func viewDidLoad()
{
....
self.textField1.addTarget(self, action: Selector("yourNameFunction:"), forControlEvents: UIControlEvents.EditingChanged)
}
func yourNameFunction(sender: UITextField) {
if sender.text.isEmpty {
// textfield is empty
} else {
// text field is not empty
}
}
if let ... where ... {
Swift 3:
if let _text = theTextField.text, _text.isEmpty {
// _text is not empty here
}
Swift 2:
if let theText = theTextField.text where !theTextField.text!.isEmpty {
// theText is not empty here
}
guard ... where ... else {
You can also use the keyword guard :
Swift 3:
guard let theText = theTextField.text where theText.isEmpty else {
// theText is empty
return // or throw
}
// you can use theText outside the guard scope !
print("user wrote \(theText)")
Swift 2:
guard let theText = theTextField.text where !theTextField.text!.isEmpty else {
// the text is empty
return
}
// you can use theText outside the guard scope !
print("user wrote \(theText)")
This is particularly great for validation chains, in forms for instance. You can write a guard let for each validation and return or throw an exception if there's a critical error.
As now in swift 3 / xcode 8 text property is optional you can do it like this:
if ((textField.text ?? "").isEmpty) {
// is empty
}
or:
if (textField.text?.isEmpty ?? true) {
// is empty
}
Alternatively you could make an extenstion such as below and use it instead:
extension UITextField {
var isEmpty: Bool {
return text?.isEmpty ?? true
}
}
...
if (textField.isEmpty) {
// is empty
}
use this extension
extension String {
func isBlankOrEmpty() -> Bool {
// Check empty string
if self.isEmpty {
return true
}
// Trim and check empty string
return (self.trimmingCharacters(in: .whitespaces) == "")
}
}
like so
// Disable the Save button if the text field is empty.
let text = nameTextField.text ?? ""
saveButton.isEnabled = !text.isBlankOrEmpty()
A compact little gem for Swift 2 / Xcode 7
#IBAction func SubmitAgeButton(sender: AnyObject) {
let newAge = String(inputField.text!)
if ((textField.text?.isEmpty) != false) {
label.text = "Enter a number!"
}
else {
label.text = "Oh, you're \(newAge)"
return
}
}
Maybe i'm a little too late, but can't we check like this:
#IBAction func Button(sender: AnyObject) {
if textField1.text.utf16Count == 0 || textField2.text.utf16Count == 0 {
}
}
Okay, this might be late, but in Xcode 8 I have a solution:
if(textbox.stringValue.isEmpty) {
// some code
} else {
//some code
}
I used UIKeyInput's built in feature hasText: docs
For Swift 2.3 I had to use it as a method instead of a property (as it is referenced in the docs):
if textField1.hasText() && textField2.hasText() {
// both textfields have some text
}
Swift 4.x Solution
#IBOutlet var yourTextField: UITextField!
override func viewDidLoad() {
....
yourTextField.addTarget(self, action: #selector(actionTextFieldIsEditingChanged), for: UIControlEvents.editingChanged)
}
#objc func actionTextFieldIsEditingChanged(sender: UITextField) {
if sender.text.isEmpty {
// textfield is empty
} else {
// text field is not empty
}
}
Swift 4.2
You can use a general function for your every textField just add the following function in your base controller
// White space validation.
func checkTextFieldIsNotEmpty(text:String) -> Bool
{
if (text.trimmingCharacters(in: .whitespaces).isEmpty)
{
return false
}else{
return true
}
}
I just tried to show you the solution in a simple code
#IBAction func Button(sender : AnyObject) {
if textField1.text != "" {
// either textfield 1 is not empty then do this task
}else{
//show error here that textfield1 is empty
}
}
It's too late and its working fine in Xcode 7.3.1
if _txtfield1.text!.isEmpty || _txtfield2.text!.isEmpty {
//is empty
}
Swift 4/xcode 9
IBAction func button(_ sender: UIButton) {
if (textField1.text?.isEmpty)! || (textfield2.text?.isEmpty)!{
..............
}
}
Easy way to Check
if TextField.stringValue.isEmpty {
}