Swift: Optional Text In Optional Value
you can use ??
(null coalescing operator) to unwrap it and provide a default value if it is nil
let sessionApiURL = self.session?.apiURL ?? ""
var url = "\(sessionApiURL)/api/products.json"
UIlabel text does not show optional word when setting optional text?
The text
property of UILabel
is optional. UILabel
is smart enough to check if the text
property's value is set to nil
or a non-nil value. If it's not nil
, then it shows the properly unwrapped (and now non-optional) value.
Internally, I imagine the drawRect
method of UILabel
has code along the lines of the following:
if let str = self.text {
// render the non-optional string value in "str"
} else {
// show an empty label
}
Why does UITextFIeld return optional value in Swift?
The reason is probably because you're using shouldChangeCharactersIn
which doesn't indicate the change in the character until the second character. Ideally you want the user to be notified of the correct answer after they complete the answer and submit it, in which case you want to use something like textFieldDidEndEditing
:
class MyVC: UIViewController, UITextFieldDelegate {
let textField = UITextField()
var numberLabel: UILabel {
let label = UILabel()
label.text = "100"
return label
}
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(textField)
textField.borderStyle = .roundedRect
textField.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textField.widthAnchor.constraint(equalToConstant: 200),
textField.heightAnchor.constraint(equalToConstant: 100)
])
textField.delegate = self
button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
button.tag = 1
button.backgroundColor = .black
button.setTitle("Answer", for: .normal)
self.view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.leadingAnchor.constraint(equalTo: textField.trailingAnchor),
button.widthAnchor.constraint(equalToConstant: 200),
button.heightAnchor.constraint(equalToConstant: 100)
])
}
@objc func buttonPressed(_ sender: UIButton!) {
if case let tag = sender.tag, tag == 1 {
textField.resignFirstResponder()
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
//convert string into number
let input = (numberLabel.text! as NSString).integerValue
//find answer to label when added by 1111
let answer = input + 1111
print(answer)
if let numberText = Int(textField.text ?? "0") {
print("This is number text: \(numberText)")
if answer == numberText {
//if user gets answer correct
print("correct")
} else {
//if user gets answer incorrect
print("wrong")
}
}
}
}
Swift optional in label
This is happening because the parameter you are passing to
String(stringInterpolationSegment:)
is an Optional.
Yes, you did a
force unwrap
and you still have anOptional
...
Infact if you decompose your line...
let fundsreceived = String(stringInterpolationSegment: self.campaign?["CurrentFunds"]!)
into the following equivalent statement...
let value = self.campaign?["CurrentFunds"]! // value is an Optional, this is the origin of your problem
let fundsreceived = String(stringInterpolationSegment: value)
you find out that value
is an Optional
!
Why?
- Because
self.campaign?
produces anOptional
- Then
["CurrentFunds"]
produces anotherOptional
- Finally your force
unwrap
removes oneOptional
So 2 Optionals - 1 Optional = 1 Optional
First the ugliest solution I can find
I am writing this solution just to tell you what you should NOT do.
let fundsreceived = String(stringInterpolationSegment: self.campaign!["CurrentFunds"]!)
As you can see I replaced your conditional unwrapping ?
with a force unwrapping !
. Just do not do it at home!
Now the good solution
Remember, you should avoid this guy !
everytime you can!
if let
campaign = self.campaign,
currentFunds = campaign["CurrentFunds"] {
cell.FundsReceivedLabel.text = String(stringInterpolationSegment:currentFunds)
}
- Here we are using
conditional binding
to transform the optionalself.campaign
into anon optional
constant (when possible). - Then we are transforming the value of
campaign["CurrentFunds"]
into anon optional type
(when possible).
Finally, if the IF does succeed, we can safely use currentFunds
because it is not optional.
Hope this helps.
text field receiving optional('value ) instead of value
When retrieving the value, use ! after the value. The downcast should force unwrap any optionals. Anything set as? can be force unwrapped by using !.
For example,
let intString = 7 as? String
print(intString!)
This should print "7", rather than Optional("7")
Why Is UITextField.text An Optional?
This is a historical thing. UITextField
does not make any difference between an empty string and a nil
string. In Objective-C there was no need to make a difference between them because you can call methods on nil
in Objective-C.
Also, there was no way in Objective-C to prevent users from assigning nil
to a property.
The resulting contract is that text
can be optional. In Objective-C that makes no difference.
In Swift there is not much we can do because UITextField.text
contract would have to change, possibly breaking lots of already written code. Note that even if nil
is never returned from the method, you can still assign nil
to reset the value.
You can find hundreds of similar situations in the old APIs.
Related Topics
Ios8 Custom Keyboard - Copy & Paste to Uipasteboard
Make a Uibarbuttonitem Disappear Using Swift iOS
Swift Error Handling for Methods That Do Not Throw
How to Create Several Cached Uicolor
Uiscrollview with Embedded Uiimageview; How to Get the Image to Fill the Screen
Types Conforming to Multiple Protocols in Swift
How to Change Font Size and Font Name of Uisegmentedcontrol Programmatically on Swift
Adding a Case to an Existing Enum with a Protocol
When and How to Use @Noreturn Attribute in Swift
Convert Character to Integer in Swift
Self' Captured by a Closure Before All Members Were Initialized
What Does "Get" Mean in a Protocol's Property Declaration
Call Completion Block When Two Other Completion Blocks Have Been Called
Ondelete Causing Nsrangeexception
How to Make Keyboard Dismiss When I Press Out of Searchbar on Swift
Swift Combine: How to Create a Single Publisher from a List of Publishers