Swift: Optional Text in Optional Value

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 an Optional...

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?

  1. Because self.campaign? produces an Optional
  2. Then ["CurrentFunds"] produces another Optional
  3. Finally your force unwrap removes one Optional

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)
}
  1. Here we are using conditional binding to transform the optional self.campaign into a non optional constant (when possible).
  2. Then we are transforming the value of campaign["CurrentFunds"] into a non 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



Leave a reply



Submit