Error: Cannot find an overload for 'Init' that supplied arguments - swift

I am unable to fix this issue, I'm using Xcode6.
var numbersOnscreen:Double = 0;
#IBOutlet var displabel: UILabel!
#IBAction func numbers(sender: UIButton) {
displabel.text = displabel.text + String(sender.tag-1)
numbersOnscreen = Double(displabel.text) //error line
}

Try this:
numbersOnscreen = Double(displabel.text!)!
The init method you were calling expects a String (not an optional string):
struct Double {
init?(_ text: String) { ... }
}
And keep in mind this is a failable initializer so another unwrapping (i.e., the last !) is needed as well.

Related

Cannot convert value of type 'NSControl.StateValue' to expected argument type 'Int'

I'm not sure why I can't get this to work. I'm following a video tutorial and this doesn't happen in the video, any help or advice in learning Mac OS development would be greatly appreciated.
Thanks - Image attached in link
Line 31: Cannot convert value of type 'NSControl.StateValue' to expected argument type 'Int'
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file To_do_list/ViewController.swift, line 31
Line 31 = if importantCheckbox.state == 0 {
//
// ViewController.swift
// To do list
//
// Created by on 18/11/2021.
//
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var importantCheckbox: NSButton!
#IBOutlet weak var textField: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func addClicked(_ sender: NSButton) {
if textField.stringValue != "" {
if let context = (NSApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext {
let toDoItem = ToDoItem(context: context)
toDoItem.name = textField.stringValue
if importantCheckbox.state == 0 {
//Not Important
toDoItem.important = false
} else {
//Important
toDoItem.important = true
}
// (NSApplication.shared.delegate as? AppDelegate)?.saveAction(nil)
}
}
}
}
[Cannot convert value of type 'NSControl.StateValue' to expected argument type 'Int'][1]
NSControl.StateValue is a kind of enum. The cases are .on, .off and .mixed.
You have to check for one of the cases for example
if importantCheckbox.state == .off {
or check for the rawValue
if importantCheckbox.state.rawValue == 0 {

Cannot convert value of type 'Range<String.Index>' to expected argument type 'UITextRange'

How to create range based on a string. With below code, I'm getting the error "Cannot convert the value of type 'Range' to expected argument type 'UITextRange'". FYI print(firstString[range]) successfully output "xxx".
class ViewController: UIViewController {
#IBOutlet weak var textView: UITextView!
let firstString: String = "xxx"
let secondString: String = "yyy"
override func viewDidLoad() {
super.viewDidLoad()
textView.text = firstString
}
func replace() {
var finalString: String?
let range = firstString.startIndex..<firstString.endIndex
print(firstString[range])
textView.replace(range, withText: secondString)
}
#IBAction func replaceButton(_ sender: Any) {
replace()
}
}
You have two problems in your code. First you need to apply your method in your textView text property. Second problem is that you are using the wrong method, to replace a range of your string you need to use replaceSubrange method. So your code should look something like this:
textView.text.replaceSubrange(range, with: secondString)

Call a func from another class in swift

I would like to call a function which is coded on another class.
So far I have made a struct on the file structs.swift for my data:
struct defValues {
let defCityName: String
let loadImages: Bool
init(defCity: String, loadImgs: Bool){
self.defCityName = defCity
self.loadImages = loadImgs
}
}
I have made the file Defaults.swift containing:
import Foundation
class DefaultsSet {
let cityKey: String = "default_city"
let loadKey: String = "load_imgs"
func read() -> defValues {
let defaults = NSUserDefaults.standardUserDefaults()
if let name = defaults.stringForKey(cityKey){
print(name)
let valuesToReturn = defValues(defCity: name, loadImgs: true)
return valuesToReturn
}
else {
let valuesToReturn = defValues(defCity: "No default city set", loadImgs: true)
return valuesToReturn
}
}
func write(city: String, load: Bool){
let def = NSUserDefaults.standardUserDefaults()
def.setObject(city, forKey: cityKey)
def.setBool(load, forKey: loadKey)
}
}
in which I have the two functions read, write to read and write data with NSUsersDefault respectively.
On my main ViewController I can read data with:
let loadeddata: defValues = DefaultsSet().read()
if loadeddata.defCityName == "No default city set" {
defaultCity = "London"
}
else {
defaultCity = loadeddata.defCityName
defaultLoad = loadeddata.loadImages
}
But when I try to write data it gives me error. I use this code:
#IBOutlet var settingsTable: UITableView!
#IBOutlet var defaultCityName: UITextField!
#IBOutlet var loadImgs: UISwitch!
var switchState: Bool = true
#IBAction func switchChanged(sender: UISwitch) {
if sender.on{
switchState = true
print(switchState)
}else {
switchState = false
print(switchState)
}
}
#IBAction func saveSettings(sender: UIButton) {
DefaultsSet.write(defaultCityName.text, switchState)
}
You need an instance of the DefaultsSet class
In the view controller add this line on the class level
var setOfDefaults = DefaultsSet()
Then read
let loadeddata = setOfDefaults.read()
and write
setOfDefaults.write(defaultCityName.text, switchState)
The variable name setOfDefaults is on purpose to see the difference.
Or make the functions class functions and the variables static variables and call the functions on the class (without parentheses)
From the code you posted, it seems you either need to make the write method a class method (just prefix it with class) or you need to call it on an instance of DefaultsSet: DefaultsSet().write(defaultCityName.text, switchState).
Another issue I found is that you also need to unwrapp the value of the textField. Your write method takes as parameters a String and a Bool, but the value of defaultCityName.text is an optional, so String?. This results in a compiler error.
You can try something like this:
#IBAction func saveSettings(sender: UIButton) {
guard let text = defaultCityName.text else {
// the text is empty - nothing to save
return
}
DefaultsSet.write(text, switchState)
}
This code should now compile and let you call your method.
Let me know if it helped you solve the problem

Learning Swift, Value of optional type not unwrapped when creating an object

I'm learning Swift right now, and in the course we have a lesson to make a simple app. Now I'm having problems with some text fields programming that it's not working properly.
Here is my code:
class ViewController: UIViewController {
#IBOutlet weak var refeicaoField: UITextField?
#IBOutlet weak var felicidadeField: UITextField?
#IBAction func addRefeicao(sender: UIButton) {
if refeicaoField == nil || felicidadeField == nil {
return
}
let nomeRefeicao = refeicaoField!.text
let valorFelicidade = felicidadeField!.text
let valorFelicidadeInt = Int(valorFelicidade!)
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
}
}
The problem starts here:
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
Where it says: value of optional 'Int?' not unwrapped; did you mean to use '!' or '?' and also value of optional 'String?' not unwrapped; did you mean to use '!' or '?'
I'm little confused, because in the lesson example they have done like this:
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt!)
And worked, but for me no. And if I try to put '!' at the two variables, I have an exclamation warning prompting no use for let novaRefeicao.
What's wrong?
EDIT:
Done some changes using all the tips found here, now my code is like:
class ViewController: UIViewController {
#IBOutlet weak var refeicaoField: UITextField!
#IBOutlet weak var felicidadeField: UITextField!
#IBAction func addRefeicao(sender: UIButton) {
if refeicaoField == nil || felicidadeField == nil {
return
}
let nomeRefeicao = refeicaoField!.text
let valorFelicidade = felicidadeField!.text
if nomeRefeicao == nil {
return
}
if let valorFelicidadeInt = Int(valorFelicidade!) {
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
} else {
return
}
}
}
Now I receive the error on unwrapped again, but now with the "nomeRefeicao" instead. Tried to put the '!' in it, but then it shows that let novaRefeicao is immutable value.
You should understand that the Swift language has changed a lot over the past year and that exclamation point has moved quite a bit over time. If your examples are from even mid-2015, you're looking at out-dated syntax.
Having a value with ? means that this item may contain a value... or it may not.
Having a value with ! means that you are forcibly unwrapping an object which can be rather dangerous, use it sparingly and only when you know for certain that it will not cause a crash.
If you have an optional value, you can safely unwrap it like this:
guard let unwrapped = wrapped else {
return
}
or
if let unwrapped = wrapped {
print(unwrapped)
}
A little more info, if you have an initialized optional value, what you've really got is this:
enum Optional<A> {
case None
case Some(A)
}
This is why you cannot use your value without unwrapping it... it's 'wrapped' in an optional enum that either has a value or doesn't.
Your code with a little safeguard added:
class ViewController: UIViewController {
#IBOutlet weak var refeicaoField: UITextField?
#IBOutlet weak var felicidadeField: UITextField?
#IBAction func addRefeicao(sender: UIButton) {
guard let refeicaoField = refeicaoField!.text else {
return
}
guard let felicidadeField = felicidadeField!.text else {
return
}
let nomeRefeicao = refeicaoField ?? "error" // added protection
let valorFelicidade = felicidadeField ?? "error" // added protection
let valorFelicidadeInt = Int(valorFelicidade) ?? 0 // defaults to '0' in case of issue
}
}
Both the text property of UITextField and the result of the Int(string:String) initializer return an optional value.
So you have to unwrap both in case the method expects non optional parameters.
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao!, alegriaEmComer: valorFelicidadeInt!)
The most compact syntax is
class ViewController: UIViewController {
#IBOutlet weak var refeicaoField: UITextField!
#IBOutlet weak var felicidadeField: UITextField!
#IBAction func addRefeicao(sender: UIButton) {
if let nomeRefeicao = refeicaoField.text, valorFelicidade = felicidadeField.text, valorFelicidadeInt = Int(valorFelicidade) {
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
// do something with novaRefeicao
}
}
}
The Meal initializer is only called if
refeicaoField.text is not nil
felicidadeField.text is not nil and can be converted to Int
There is no need to check the UITextField instances for nil.
If you get a runtime error, one of the fields is not connected in IB.
The message Initialization of immutable value ... is a warning, because the created Meal instance assigned to novaRefeicao is never used. That's why I added the comment line do something …
The line:
let valorFelicidadeInt = Int(valorFelicidade!)
converts a String value into an Int. What should your code do if the string cannot be converted to an integer? You need to address that explicitly.
In Swift, the conversion has a type of Optional - either the conversion worked or it did not. You thus have two cases to cover. The following is a possible approach:
if let valorFelicidadeInt = Int(valorFelicidade!) {
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
// continue using `Meal`
}
else {
// User error; text not an int
}
The if let will succeed if Int(...) returns a non-nil optional; you'll then build the Meal.
The same approach to unwrapping by handling the two options applies to other parts of your code.

Calling function in swift

I am having problems with calling the function in Swift, when building an iOS app.
#IBOutlet weak var vyseHypoteky: UITextField!
#IBOutlet weak var dobaSplaceni: UITextField!
#IBOutlet weak var urokovaSazba: UITextField!
#IBOutlet weak var mesicniSplatka: UITextField!
#IBAction func zmenaVyseHypoteky(sender: UISlider) {
var currentValue = Int(sender.value)
vyseHypoteky.text = "\(currentValue)"
vypoctiSplatku()
}
#IBAction func zmenaDobySplaceni(sender: UISlider) {
var currentValue = Int(sender.value)
dobaSplaceni.text = "\(currentValue)"
}
#IBAction func zmenaUrokoveSazby(sender: UISlider) {
var currentValue = Int(sender.value)
urokovaSazba.text = "\(currentValue)"
}
func vypoctiSplatku () {
let HU:Int? = vyseHypoteky.text.toInt()
let ipa:Int? = urokovaSazba.text.toInt()
let n:Int? = dobaSplaceni.text.toInt()
var ipm = ipa! / 12
var zavorka = 1+ipm
var vypoctenaZavorka = mocnina(mocnenec: zavorka, mocnitel: n)
var citatel = HU! * ipm * vypoctenaZavorka
var jmenovatel = vypoctenaZavorka - 1
var splatka = citatel / jmenovatel
mesicniSplatka.text = ("\splatka")
}
func mocnina (mocnenec: Int, mocnitel: Int) -> Int {
var mocnina = 1
for _ in 1...mocnitel {
mocnina *= mocnenec
}
return mocnina
}
The app is calculating a number by my formula. I want to use my function to calculate the x^y, this the "mocnina" function where I want to use two int, the x is "mocnenec" and the y is "mocnitel".
And finally I want to send the final int from variable "splatka" to text inout filed "mesicniSplatka".
But I am getting errors in calling the function "mocnina" --> var vypoctenaZavorka = mocnina(mocnenec: zavorka, mocnitel: n)
Extraneous argument label 'mocnenec:' in call
Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?
and in the end with mesicniSplatka.text = ("\splatka")
Invalid escape sequence in literal
How to fix it? Thx for helping a total newbie :)
The problem is that n is a wrapped:
var n:Int?
So you have a few options, you can either change your code to unwrap it when you use it (probably a good idea to check for nil before doing this as this will cause an exception if n is nil):
var vypoctenaZavorka = mocnina(mocnenec: zavorka, mocnitel: n!)
Or you can unwrap it when you create it:
let n:Int = dobaSplaceni.text.toInt()!
If you'd like to better understand "when to use optionals", I've written a very long explanation to this question on the subject: UIViewController variables initialization
In your code, n is declared of type Int?, it means "Optional Int". This is normal because the toInt() function is not guaranteed to succeed, and might return nil if the text is not convertible to an integer. So, you need to unwrap it first, like this: var vypoctenaZavorka = mocnina(mocnenec: zavorka, mocnitel: n!). Or, if you're not sure the conversion from string succeeded, do something like this:
let HU:Int? = vyseHypoteky.text.toInt()
let ipa:Int? = urokovaSazba.text.toInt()
let n:Int? = dobaSplaceni.text.toInt()
if ipa != nil {
var ipm = ipa! / 12
var zavorka = 1+ipm
if n != nil {
var vypoctenaZavorka = mocnina(mocnenec: zavorka, mocnitel: n)
// etc...
}
}