I have a textfield and I want it to hide and show when a button is pressed, and I also want the text in the textfield to be passed to a label just underneath the textfield. I tried this :
#IBAction func myfunction(_ sender: UIButton) {
if textfield.isHidden == true{
textfield.isHidden = false
}else{
label.text = textfield.text
textfield.isHidden = true
}
}
Apparently the hidding and showing part is working but the line
label.text = textfield.text
is not. I get an error like this "Thread 1: EXC_BREAKPOINT (code=1, subcode=0x10143fb50" and in the console I have "fatal error: unexpectedly found nil while unwrapping an Optional value"
Can someone help me please.
Based on your error, it seems that you try to affect with this line label.text = textfield.text the text from your textfield into label but the problem is that your textfield.text is nil.
That's why you have the error unexpectedly found nil while unwrapping an Optional value
Your textfield is an Optional. It can have a value or nil. If you try to unwrap an optional value having nil you have this kind of error.
The solution here is to unwrap safely the optional value with Optional Binding like this :
if let textInput = textfield.text {
//There is a text in your textfield so we get it and put it on the label
label.text = textInput
} else {
//textfield is nil so we can't put it on the label
print("textfield is nil")
}
Here is a simpler code you may try. The nil-coalescing operator (a ?? b) unwraps an optional a. if it contains a value, or returns a default value b if a is nil.
#IBAction func myfunction(_ sender: UIButton) {
label.text = textfield.text ?? ""
}
Related
I was wondering if there is a way to check if a text field contains a certain character and if that is the case, change the keyboard type displayed. This is what I have tried but it does not manage to change. This is action occurs when editing the text field is changed.
#IBAction func decOrNot(_ sender: Any) {
let cont = "1"
let field = testKaede.text
if (field!.contains(cont)) {
self.testKaede.keyboardType = UIKeyboardType.numberPad
}
else {
self.testKaede.keyboardType = UIKeyboardType.decimalPad
}
}
Just call reloadInputViews() on your UITextField after you change keyboard's type
textField.keyboardType = .numberPad
textField.reloadInputViews()
This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 4 years ago.
I have put a full-screen size invisible button behind of all objects(like textfield, picker.. ) to close opened keyboard. I call below function when the button is clicked:
func hideKeyboard() {
for view in self.contentViewOutlet.subviews {
if let tField = view as? UITextField {
tField.resignFirstResponder()
}
}
}
but I get this error after I click the button:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
I roughly know what does it mean but I couldn't write a solution. (Actually, this hideKeyboard() function was working fine. It starts to give an error after I add UIPickerView)
Your contentViewOutlet is an Outlet so it might be nil, but it's implicitly unwrapped. And you get this error because when you tap a button, this object is nil. To avoid the crash, change your code to
func hideKeyboard() {
guard let contentView = self.contentViewOutlet else { return }
for view in contentView.subviews {
if let tField = view as? UITextField {
tField.resignFirstResponder()
}
}
}
After that, your method won't do anything if contentViewOutlet is nil.
When I enter a value in the UiTextField and press add button the app works perfectly fine,but when I don't enter a value in the UiTextField, then press the add button the whole app crashes. can someone please help me and show me the light.Thank you in advance and good wishes for you and your family.
This is my code
import UIKit
class ViewController: UIViewController,UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.textFild.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet var textFild: UITextField!
#IBAction func ButtonAwesome(sender: AnyObject) {
let value:Double = Double(textFild.text!)!
let sum:Double = value - 1;
let alert = UIAlertController(title: "km", message: "\(sum)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Exit", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert,animated: true, completion: nil)
}
func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString stringer: String) -> Bool
{
if (textField.text == "" && (stringer == ".")) {
return false;
}
let countdots = textField.text!.componentsSeparatedByString(".").count - 1
if countdots > 0 && stringer == "."
{
return false
}
return true
}
}
A more robust solution would be to use the nil coalescing operator to assert that the initialization of value never fails.
#IBAction func ButtonAwesome(sender: AnyObject) {
let value = Double(textFild.text ?? "0") ?? 0
let sum:Double = value - 1;
let alert = UIAlertController(title: "km", message: "\(sum)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Exit", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert,animated: true, completion: nil)
}
This is valid for any of the following "unexpected" values of textField.text: nil, "" (empty) or some character that cannot be used to initialize a Double type variable (e.g. "a"). For all these cases, value is give a value of 0.
As an example, consider the following comparisons between a safe and an un-safe way of solving your initial runtime exception.
We first look at the dangers of forcibly unwrapping optionals - not a safe solution. What if textField.text contains nil or an non-numerical character, e.g. "a"? Result:
var myTextFieldText : String? = nil
/* Example 1: nil value causes runtime error */
if myTextFieldText != "" { // this is 'true' -> enter if closure
let value:Double = Double(myTextFieldText!)!
/* this will fail at run time since we are forcibly (un-safely)
unwrapping an optional containing 'nil' */
}
/* Example 2: non-numeric string character causes runtime error */
myTextFieldText = "a"
if myTextFieldText != "" { // this is 'true' -> enter if closure
let value:Double = Double(myTextFieldText!)!
/* this will fail at run time since we cannot initalize a
Double with a string value "a", hence 'Double(myTextFieldText!)'
returns nil, but since we've appended '!', we, like above,
forcibly tries to unwrap this optional of value nil */
}
You should, generally, always use conditional unwrapping of optionals, to avoid encountering a nil value when forcibly unwrapping optionals, the latter leading to a runtime error.
A more robust version of the example above, making use of the nil coalescing operator:
myTextFieldText = nil
let valueA = Double(myTextFieldText ?? "0") ?? 0 // 0
/* OK, Double(myTextFieldText ?? "0") = Double("0") = 0 */
myTextFieldText = "a"
let valueB = Double(myTextFieldText ?? "0") ?? 0 // 0
/* OK, Double(myTextFieldText ?? "0") = Double("a") = nil (fails)
=> use rhs of outer '??' operator: nil ?? 0 = 0 */
For an alternative method, where you extend UITextField to cover your string to numerical type conversion needs, see Leos neat answer in the following thread:
Swift - Converting String to Int
The thread also contains some other valuable insights w.r.t. reading text as numerical values from UITextField instances.
Finally, when dealing with String to Double value conversion, it might be appropriate to use a fixed precision w.r.t. number of decimal digits in your resulting Double value. For a thorough example of how to do this using NSNumberFormatter and extensions, see:
How to input currency format on a text field (from right to left) using Swift?
Please replace your buttonAwesome method with the following code where you check if textfield is not empty, this will work if textfield has a value:
#IBAction func ButtonAwesome(sender: AnyObject) {
if textFild.text != "" {
let value:Double = Double(textFild.text!)!
let sum:Double = value - 1;
let alert = UIAlertController(title: "km", message: "\(sum)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Exit", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert,animated: true, completion: nil)
}
}
Since textfield.text is an optional value and as in your case textfield can or cannot have text. So you should test for optional as give below.
if let textIsAvailable = textfield.text
{
print("Text \(textIsAvailable)")
}
Note : The reason for your crash is you are trying to access value which actually doesn't have any value.
I've written a simple application using Swift and Xcode 6.1.1. The program, which is a simple calculator, works well but I haven't been able to validate non-nil input for the three text fields. As a result, if the user leaves the field blank and then hits "calculate," the application crashes.
The app takes three inputs, initially as strings. I wrote an if statement to check for nil but it doesn't work - it will just pass to else regardless. Here's the code block that's relevant to my question:
...
#IBOutlet var calcButton: UIBarButtonItem!
#IBOutlet var yearOneField: UITextField!
#IBOutlet var yearTwoField: UITextField!
#IBOutlet var yearThreeField: UITextField!
#IBOutlet var displayWindow: UILabel!
#IBAction func calcButtonTapped(sender: AnyObject) {
if (yearOneField == nil) {
displayWindow.text = ("Non-zero entries are not permitted. Please enter new values.")
} else {
let yearOne = yearOneField.text.toInt()
let yearTwo = yearTwoField.text.toInt()
let yearThree = yearThreeField.text.toInt()
...
I was thinking I could evaluate the IBOutlet for nil but that didn't work. I'm new to Swift and Xcode so I hope this is a n00b question to the more experienced developers out there. Thank you.
The only way the #IBOutlets could be nil is if you forgot to wire them up in Interface Builder. Usually you don't need to check that because the crash will tell you to fix that problem.
The toInt() function returns an Optional Int (aka Int?) that must be unwrapped before being used. toInt() will return nil if the value in the text field does not represent a valid Int. "2.1", "seven", and "" would all return nil if converted with toInt(). I recommend you use optional binding (if let) syntax to check the conversion for nil and unwrap the result if it is not nil:
if let yearOne = yearOneField.text.toInt() {
if let yearTwo = yearTwoField.text.toInt() {
if let yearThree = yearThreeField.text.toInt() {
// yearOne, yearTwo, and yearThree are all valid Ints
// so do the calculations
}
}
}
Alternatively, if you know you want to use a default value (like 0) when the field can't be converted to an Int, you can unwrap the result using the nil coalescing operator ?? like so:
let yearOne = yearOneField.text.toInt() ?? 0
let yearTwo = yearTwoField.text.toInt() ?? 0
let yearThree = yearThreeField.text.toInt() ?? 0
The text fields themselves will never be nil. They are created and assigned during initialization, and you're never removing them.
I think you want to check if their text properties contain any text, which you can do like this:
Updated for Swift 2:
if let text = yearOneField.text where !text.isEmpty {
// perform the conversions
} else {
// the text field is empty
}
You can avoid nesting using guard:
guard let text = yearOneField.text where !text.isEmpty else {
// the text field is empty
return
}
// perform the conversions
I prefer the guard syntax because it's clearer about what the ideal result is.
You can just check as you do with normal optionals.
guard let unwrapped = myLabel else {return}
Or like this
if myLabel == nil {
//do stuff
}
Or like this:
if let unwrappedLabel = myLabel {
}
I am trying to evaluate the contents of a form field that, when empty is throwing an error.
Here is the outlet code
#IBOutlet var txtUsername : UITextField!
Here is the println for the target field.
println("\(txtUsername)")
<UITextField: 0x10e8280a0; frame = (20 40; 280 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x10e828b20>; layer = <CALayer: 0x10e828300>>
So, looking at this I would assume that txtUsername.text is empty or == "". But everything I try to do to evaluate this throws an error.
if countElements(txtUsername.text as String) != 0 {
... code here
}
if txtUsername.text.bridgeToObjectiveC().length != 0 {
... code here
}
if txtUsername.text.utf16count != 0 {
... code here
}
if txtUsername.text != "" {
... code here
}
All bring back "EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Also, evaluating whether it is nil doesn't seem to work. The below scripts show that there is something to be evaluated, even though it is blank. The problem is telling whether or not it is blank.
If the field was nil, I would expect it to return false and trigger the else statement.
if let evalText = txtUsername.text{
println("There is something here : \(evalText)")
} else {
println("text is nil")
}
// This returns "There is something here:"
if txtUsername.text{
println("There is something here")
} else {
println("text is nil")
}
// This returns "There is something here"
I have even tried to set the value in a variable, only to have it kick out the error after hitting the "if" statement.
Thanks,
EXC_BAD_INSTRUCTION implies an assertion failure. This is most common when something is nil but you are still trying to operate on it.
The text property of UITextField is an Implicitly Unwrapped Optional (String!). You must first check if it is nil. Your app is crashing because it is nil.
txtUsername.text is an optional in Swift. Even your label is an optional so it's not really safe to use ! when declaring it. But anyway, try using this:
if let currentText = txtUsername.text {
// ... Do something with currentText ...
}
else {
NSLog("Text is nil")
}
To be extra sure you can even check if txtUsername is set in the same way. So in the end you will have this:
if let currentTxtUsername = txtUsername{
if let currentText = currentTxtUsername.text {
// ... Do something with currentText ...
}
else {
NSLog("Text is nil")
}
}
else {
NSLog("Text label is nil")
}
Don't forget to remove the ! in the declaration part though.
Turned out to be an error ghosting issue.
The actual problem was that it would get further down in the code and run into a situation where I was inadvertently trying to put nil data from a core data object back into the text string. Setting a text field to nil doesn't work, but rather than error where the problem was, it erred at the "if" statement 20 lines above it.
Below is the full code, and some description of the issue.
#IBAction func btnLoad(sender : AnyObject) {
var appDel = (UIApplication.sharedApplication().delegate as AppDelegate)
var context = appDel.managedObjectContext
var request = NSFetchRequest(entityName: "Users")
request.returnsObjectsAsFaults = false
// Here is the place where it throws the error.
if txtUsername.text == "" {
request.predicate = NSPredicate(format: "username = %#", "\(txtUsername.text)")
}
var results = context.executeFetchRequest(request, error: nil)
println(results)
if(results.count > 0){
var res = results[0] as NSManagedObject
println("\(res)")
//*** The database had nil values for the result selected. And nil doesn't go into a text field.
txtUsername.text = res.valueForKey("username") as String
txtPassword.text = res.valueForKey("password") as String
responseLabel("User Found")
} else {
responseLabel("No Users Found")
}
}
Thanks everyone for replying.