I want to accept user input in a range, but keep on getting error:
Cannot convert value of type Range<Int32> to expected argument type Range<_>
I am learning Swift but I did not understand the different scenarios to convert UITextField to text and maybe integer.
class ViewController: UIViewController {
#IBOutlet weak var Range1: UITextField!
#IBOutlet weak var Range2: UITextField!
#IBOutlet weak var TheNUmber: UITextField!
#IBOutlet weak var OutletLabel: UILabel!
#IBAction func Guess(_ sender: UIButton) {
var R1 = (Range1.text! as NSString).intValue
var R2 = (Range2.text! as NSString).intValue
//print(R1, " ", R2)
var answer = Int.random(in: R1..<R2)
// I tried my best to use custom range from UItext field but did not work.
//I need more help.
print ("Random Number: \(answer)")
var turn = 0;
if(((R1>1)&&(R1<1000))&&((R2>1)&&(R2<1000))){
for i in 1...5{
let guess = (TheNUmber.text! as NSString).intValue
turn = i;
//let guess = (TheNUmber.text! as NSString).intValue
if(guess == answer){
OutletLabel.text = ("Yes, it is \(answer).")
OutletLabel.text = ("It took you \(turn) tries.")
break
}
else if(guess>answer){
OutletLabel.text = ("Lower!")
}
else if (guess<answer){
OutletLabel.text = ("Higher!")
}
else{
continue;
}
}
if (turn > 5){
OutletLabel.text = ("Sorry, it was \(answer).")
}
}
else{
OutletLabel.text = ("Keep the numbers between 1 and 100.")
}
}
#IBAction func Reset(_ sender: Any) {
self.Reset (sender)
}
I am not sure about this error. Please help me with the range.
The problem is that intValue returns an Int32, not an Int. So change
var R1 = (Range1.text! as NSString).intValue
var R2 = (Range2.text! as NSString).intValue
var answer = Int.random(in: R1..<R2)
To
let R1 = Int((Range1.text! as NSString).intValue)
let R2 = Int((Range2.text! as NSString).intValue)
let answer = Int.random(in: R1..<R2)
Even better, don't use NSString or intValue. Use Swift.
let R1 = Int(Range1.text!)!
let R2 = Int(Range1.text!)!
let answer = Int.random(in: R1..<R2)
Be aware that this code can crash — for example, if the user types "howdy" instead of an integer. But you need to deal with that.
Your code has other issues, but at least you will get past this one.
Related
I am a beginner with Xcode and Swift. Below is my formula for the mortgage calculator. It is working correct in Playground but when I transfer it to the ViewController tab that is when Xcode is giving me a bunch of errors. Can someone please help?
let r: Double = interestRate / 1200
let n: Double = years * 12
let p: Double = pow(1 + r, n)
let monthPay = loan * r * p / (p - 1)
print(monthPay)
So in my View Controller
valueA is Loan Amount
valueB is Number of Payments
valueC is Interest Rate
underneath that you will have a calculate button that will print the results underneath in a label currently named results. It may be that when i rename everything to the values is when the issues occur.
ViewController Code
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var valueA: UITextField!
#IBOutlet weak var valueB: UITextField!
#IBOutlet weak var valueC: UITextField!
#IBOutlet weak var results: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func button(_ sender: Any) {
let a = Int(valueA.text!)
let b = Int(valueB.text!)
let c = Int(valueC.text!)
let answer = a! * c! * pow(1 + c!, b!) / (pow(1 + c!, b!))
results.text = "$\(answer)"
}
}
Your issue is that you are converting your textfield values to integers and trying to multiply them by the result of pow's method which returns a Double. Note that if the user enters an invalid value your app will crash if you force unwrap the result. Yo can use nil coalescing operator ?? to provide a default value .zero in case of failure. Try like this:
class ViewController: UIViewController {
#IBOutlet weak var valueA: UITextField! // loan amount
#IBOutlet weak var valueB: UITextField! // Number of Payments
#IBOutlet weak var valueC: UITextField! // Interest Rate
#IBOutlet weak var results: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func button(_ sender: Any) {
let loanAmount = Double(valueA.text!) ?? .zero
let numberOfPayments = Double(valueB.text!) ?? .zero
let interestRate = Double(valueC.text!) ?? .zero
let rate = interestRate / 100 / 12
let answer = loanAmount * rate / (1 - pow(1 + rate, -numberOfPayments))
results.text = Formatter.currency.string(for: answer)
}
}
extension Formatter {
static let currency: NumberFormatter = {
let formatter = NumberFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.numberStyle = .currency
return formatter
}()
}
I'm a beginner and I am struggling with a certain problem regarding local variables. Specifically, I am trying to make an app where I test certain fraction questions. So, I need to generate random numbers for the test and access them so that the checker function can make sure the user got the right answer. However, if I generate a new set of numbers when the user clicks "ask question", the other checker function doesn't know what those numbers are... Here is my code below:
class ViewControllerEasy: UIViewController {
#IBOutlet weak var giveQuestionOutlet: UIButton!
#IBOutlet weak var nextButtonOutlet: UIButton!
#IBAction func nextQuestionButton(_ sender: Any) {
nextButtonOutlet.isHidden = true
giveQuestionOutlet.isEnabled = true
easyQuestionResponse.text = ""
easyQuestionLabel.text = ""
resultLabel.text = ""
}
#IBOutlet weak var easyQuestionResponse: UITextField!
#IBOutlet weak var easyQuestionLabel: UILabel!
#IBAction func easyQuestionButton(_ sender: Any) {
let num1 = Int.random(in: 1 ..< 6)
let num2 = Int.random(in: 2 ..< 11)
easyQuestionLabel.text = "What percentage does \(num1) / \(num2) represent? (Round down to the closest whole number)"
}
#IBOutlet weak var resultLabel: UILabel!
#IBAction func checkButton(_ sender: Any) {
let expectedAnswer = ((num1 * 100) / num2)
let expectedAnswer2 = Float(expectedAnswer)
if Float(easyQuestionResponse.text!) == round(expectedAnswer2) {
resultLabel.text = "Great Job! Correct Answer."
nextButtonOutlet.isHidden = false
giveQuestionOutlet.isEnabled = false
}else {
resultLabel.text = "Sorry, that is incorrect. The correct answer was: \(round(expectedAnswer2))%"
nextButtonOutlet.isHidden = false
giveQuestionOutlet.isEnabled = false
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let invalidCharacters = CharacterSet(charactersIn: "0123456789").inverted
return string.rangeOfCharacter(from: invalidCharacters) == nil
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
So, how can I generate new questions when the user clicks the button to ask for it and also make sure that the code can check whether or not the user got the right answer? I tried looking at using a global variable, but that would keep the values same after the first execution of the random numbers call. Thus, I hope someone can help me with this problem. Thanks in advance.
Absolute rookie here, stumbling my way through trial and error. I have come across a problem I cannot solve, despite searching here for hours, and trying many different ideas. The error I am receiving is (TotalFuelLoad.text line):
Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
The code is as follows:
import UIKit
class FirstViewController: UIViewController {
#IBOutlet weak var LeftMainTankQuantity: UITextField!
#IBOutlet weak var RightMainTankQuantity: UITextField!
#IBOutlet weak var AuxTankQuantity: UITextField!
#IBOutlet weak var TailTankQuantity: UITextField!
#IBOutlet weak var TotalFuelLoad: UILabel!
#IBAction func TankFuelChanged(_ sender: Any) {
let LeftMainTankQuantityValue = Int(LeftMainTankQuantity.text!)
let RightMainTankQuantityValue = Int(RightMainTankQuantity.text!)
let AuxTankQuantityValue = Int(AuxTankQuantity.text!)
let TailTankQuantityValue = Int(TailTankQuantity.text!)
TotalFuelLoad.text = String(describing: (LeftMainTankQuantityValue ?? 0) + (RightMainTankQuantityValue ?? 0) + (AuxTankQuantityValue ?? 0) + (TailTankQuantityValue ?? 0))
}
}
Any ideas or suggestions would be most appreciated.
I'd suggest doing this in 3 stages:
Use ?? twice to safely unwrap and convert your values to Int.
Add your values up to create total.
Use string interpolation to convert total to String.
#IBAction func TankFuelChanged(_ sender: Any) {
let leftMainTankQuantityValue = Int(LeftMainTankQuantity.text ?? "") ?? 0
let rightMainTankQuantityValue = Int(RightMainTankQuantity.text ?? "") ?? 0
let auxTankQuantityValue = Int(AuxTankQuantity.text ?? "") ?? 0
let tailTankQuantityValue = Int(TailTankQuantity.text ?? "") ?? 0
let total = leftMainTankQuantityValue + rightMainTankQuantityValue + auxTankQuantityValue + tailTankQuantityValue
TotalFuelLoad.text = "\(total)"
}
Just starting learning swift but stuck when trying to multiply an input with another number and display on a label. I get the error that the number isn't a string and tried to cast but didn't work.
class ViewController: UIViewController {
#IBOutlet weak var entry: UITextField!
#IBOutlet weak var answer: UILabel!
#IBAction func button(_ sender: Any) {
answer.text = entry.text * 2
}
}
You should cast the text into a Double, an Int etc., then convert the calculation to a string.
if let entry = Double(entry.text) {
answer.text = "\(entry * 2)"
}
or
if let entry = Int(entry.text) {
answer.text = "\(entry * 2)"
}
If you know that the entry will hold a number
answer.text = String(Int(entry.text)! * 2)
Using optional unwrapping instead
if let num = Int(entry.text) {
answer.text = String(num * 2)
}
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...
}
}