1

In my application I have a textbox that should be filled with a Double and the number should be saved into a variable but there's an error. I dragged and dropped the textbox into ViewController.swift so it should be linked. I created a @IBOutlet. I called the textbox mmolText and the variable mmol. I tried something like: var mmol = mmolText.text but it shows an error:

'ViewController.Type' does not have a member named 'mmolText'.

What's the problem? How can I solve it? Besides the type of the content of the textbox is a string but I should convert it into Double.

screenshot

Here the code of ViewController.swift is:

import UIKit class ViewController: UIViewController { @IBOutlet weak var mmolText: UITextField! var mmol = mmolText.text @IBOutlet weak var mmolLabel: UILabel! @IBOutlet weak var mgLabel: UILabel! @IBAction func convertBM(sender: AnyObject) { } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } 
0

3 Answers 3

2

It seems like we probably simply want mmol to exist as a convenient way for getting the text property out of the mmolText textfield, right? So why not use a computed property:

var mmol: String { get { return mmolText.text ?? "" } set { mmolText.text = newValue } } 

The get makes use of the nil coalescing operator. UITextField's text property hasn't been updated with the Objective-C nullability annotations yet, so we need to handle the case of it potentially returning nil.

If we want this to be readonly, we can simply omit the set part.


If we want this as a Double, we can modify the above computed property to look more like this:

var mmol: Double { get { return ((mmolText.text ?? "0") as NSString).doubleValue } set { mmolText.text = String("%f", newValue) } } 

And again, if we want this to be readonly, we can simply omit the set half. And of course, the format string can be played around with to get the string version of the double to show up exactly as you intend when using this set method.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer. I just started learning iOS development. Yes, It can be just "readonly" so we can avoid to use "set". Anyway isn't it possible to use just the "=" operator instead of "get"? And just use an "if" condition for testing wether the textbox is empty or not? Since I'm new to iOS development I'd prefer the easiest solution.
To make it readonly, just delete the set part. You can use the = operator, but now you have to set it with the = operator everytime the textbox changes. Using this approach, the mmol property just fetches from the textbox any time it is accessede. There's a way to write this using an if condition, but there's nothing complicated about ??. This is the easiest solution. It's also the best solution.
@Fabio You can read up on Swift's nil coalescing operator (??) here in the Basic Operators section of the Swift online documentation.
Thank you again @nhgrif. I just asked because I've learnt the "=" but I didn't encounter "get" yet so it was easier for me to use a method that I already know, anyway I understand the logic of your code and it seems better. Besides it isn't hard after all.
Thank you for pointing me to the relevant Swift documentation.
1
class ViewController: UIViewController { @IBOutlet weak var mmolText: UITextField! var mmol: String! override func viewDidLoad() { super.viewDidLoad() mmol = mmolText.text } } 

This way it works. I can remember something like because at that stage, the properties can exist. Which means, it can be there or it isn't. That's why you can't do it like that.

Don't pin me on this explanation though, I'm not very sure.

4 Comments

Thank you. I added "var mmol: String!" as you suggested, then I added "mmol = mmolText.text" inside "@IBAction func convertBM(sender: AnyObject) {}" because I want it to occur when the button is pressed. Then I used the println() function for checking the value of the variable. It works now, though the variable type is String. I would like to input numbers with decimals so i'd like to convert the String into a Double. I know for integers there's the method .toInt(), how can I do for Doubles?
I'm downvoting because this sort of answer encourages a question days/weeks/months/whenever from now about "unexpectedly incountered nil while unwrapping an optional". There's a time and a place for implicitly unwrapped optionals and this is definitely not it. Besides, as my answer outlines, there's a way better approach to this problem.
@nhgrif Like I said, it's opinion based. It's not up to you to decide what's right and whatnot. Sure, I agree it's not the best place to use it. A simple comment would be suffice and I would have changed it and keeping it in mind for the next time I try to help someone. Whether there are better ways to solve it is even more of an opinion. I'm pretty sure SO isn't a place for opinions.
If you want to argue about how I should be using my downvotes, you're welcome to take it up on the meta, or invite me to a chat.
0

mmolText is a property on self. You can't refer to it there because self has not been initialized yet.

You'll have to assign it within awakeFromNib, viewDidLoad, etc.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.