I am using Swift and I want to know how I can store user input as a variable (it’s a double).
I'm still in the learning states so I have been watching youtube tutorials on the situation but nothing helped.
My code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var userInput: UITextField!
override func viewDidLoad() {
userInput.delegate = self
}
#IBAction func Increment(_ sender: UIButton) {
var inc = 0
userInput = userInput + inc
}
#IBAction func Decrement(_ sender: UIButton) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
userInput.resignFirstResponder()
}
}
extension ViewController: UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
The user will be able to enter a number and increment or decrement the number by a certain input value.
//fetch any number from textfield
func getValueFromTextfield() -> Double?{
guard let text = userInput.text else {
print("Missing user input")
return nil
}
guard let doubleValue = Double(text) else {
print("parse failure")
return nil
}
return doubleValue
}
// Now for increment and decrement we have methods be like, Am assuming certain input value as 1 to be used for increment and decrement replace this if needed
func increment(){
// get value
if let value = getValueFromTextfield(){
userInput.text = “\(value + 1)” // increment by 1
}
}
func decrement(){
// get value and check if it’s greater than zero
if let value = getValueFromTextfield(), value > 0{
userInput.text = “\(value - 1)” // decrement by 1
}
}
#IBAction func Increment(_ sender: UIButton) {
increment()
}
#IBAction func Decrement(_ sender: UIButton) {
decrement()
}
These method will help you achieve increment or decrement operation without need to store value in any variable.
If you still want to save value in variable just simply store value returned from method let valueToStore = getValueFromTextfield()
Your code won't compile correctly but the answer to your question is:
let doubleValue = Double(userInput.text!)! converts your code to double
or better using optional unwrapping:
guard let text = userInput.text else {
print("text of userInput is nil")
return
}
guard let doubleValue = Double(text) else {
print("Impossible to parse \(text) into Double")
return
}
print(doubleValue)
#IBAction func Increment(_ sender: UIButton) {
if let text = userInput.text, var doubleText = Double(text) {
doubleText = doubleText + 1
userInput.text = "\(doubleText)"
}
}
Similarly you can write for Decrement.
#IBAction func Increment(_ sender: UIButton) {
var inc = 0
userInput.text = ( Double(userInput.text) + Double(inc) ).rounded(toPlaces: 1)
}
Related
I don't use storyboards.
I want to send protocol data using #objc button action.
However, the sent view controller does not run the protocol function.
May I know what the reason is?
In fact, there's a lot more code.
Others work, but only protocol functions are not executed.
The didUpdataChampion function is
Data imported into a different protocol.
I have confirmed that there is no problem with this.
protocol MyProtocolData {
func protocolData(dataSent: String)
func protocolCount(dataInt: Int)
}
class PickViewController: UIViewController,ChampionManagerDelegate{
static let identifier = "PickViewController"
var count = 0
var urlArray = [URL]()
var pickDelegate : MyProtocolData?
override func viewDidLoad() {
super.viewDidLoad()
champions.riot(url: "myURL")
}
#objc func topHand(){
pickDelegate?.protocolData(dataSent: "top")
print(count)
pickDelegate?.protocoCount(dataInt: count)
let cham = ChampViewController()
cham.modalPresentationStyle = .fullScreen
present(cham, animated: true, completion: nil)
}
//Data imported to another protocol
func didUpdataChampion(_ championManager: ChampionManager, champion: [ChampionRiot]) {
print(#function)
count = champion.count
for data in champion {
let id = data.id
guard let url = URL(string: "https://ddragon.leagueoflegends.com/cdn/11.16.1/img/champion/\(id).png") else { return }
urlArray.append(url)
count = urlArray.count
}
}
func didFailWithError(error: Error) {
print(error)
}
}
class ChampViewController: UIViewController,MyProtocolData {
var pickData = ""
var arrayCount = 0
override func viewDidLoad() {
super.viewDidLoad()
}
func protocolData(dataSent: String) {
print(#function)
pickData = dataSent
print(pickData)
}
func protocoCount(dataInt: Int) {
print(#function)
arrayCount = dataInt
print(arrayCount)
}
}
i don't see full code, for instance how you call bind to topHand(), my advice is:
check that topHand - is called
check that pickDelegate isn't nil inside topHand
Create Object fo your PickViewController class and set its delegate to self.
var yourObj = PickViewController()
override func viewDidLoad() {
super.viewDidLoad()
yourObj.delegate = self
}
My intention is to run performSegue solely if all textfields are filled. If not, the button is not supposed to work - to be exact, performSegue shall not be executed.
My approach was to put performSegue inside of an if statement, but somehow it's being ignored and performSegue is being executed anyways, even though both fields are empty. Is there another more successful approach?
#IBAction func buttonAdd(_ sender: Any) {
if (addKmInput.text! != "" && addPriceInput.text != "") {
...
performSegue(withIdentifier: "goBackToSecond", sender: self)
}
}
#IBOutlet weak var addKmInput: UITextField!
#IBOutlet weak var addPriceInput: UITextField!
New version:
#IBAction func buttonAdd(_ sender: Any) {
performSegue(withIdentifier: "goBackToSecond", sender: self)
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
switch identifier {
case "goBackToSecond":
return shouldGoBackToSecond()
default:
return true
}
}
func shouldGoBackToSecond() -> Bool {
guard let kmInput = addKmInput.text, let priceInput = addPriceInput.text else { return false }
return !kmInput.isEmpty && !priceInput.isEmpty
}
Try following solution:
#IBAction func buttonAdd(_ sender: Any) {
if shouldGoBackToSecond() {
performSegue(withIdentifier: "goBackToSecond", sender: self)
}
}
func shouldGoBackToSecond() -> Bool {
guard let kmInput = addKmInput.text, let priceInput = addPriceInput.text else { return false }
return !kmInput.isEmpty && !priceInput.isEmpty
}
use str.isEmpty to check if the string int he textField is empty :
if let t1 = addKmInput?.text, let t2 = addPriceInput?.text, !t1.isEmpty, !t2.isEmpty {
...
performSegue(withIdentifier: "goBackToSecond", sender: self)
}
and you should ideally use this delegate to deny segue performance:
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
return true //return true/false conditionally. returning false will prevent segue performance.
}
I have been trying to create an app that randomly prints a new word after a certain amount of time, i.e five seconds.
import UIKit
class ViewController: UIViewController {
var myTimer : Timer!
var theValue = 0
#IBOutlet weak var textLabel: UILabel!
#IBOutlet weak var InspireLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib
}
override func viewDidDisappear(_ animated: Bool) {
self.myTimer.invalidate()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#objc func updateMyLabel() {
theValue += 1
self.textLabel.text = String(theValue)
}
func randomText() -> String {
if theValue > 5 {
let words = ["Place", "Cat", "House"]
return words.randomElement() ?? "" //Use default method to get random element from Array
}
return "string if theValue < 5 or equal to 5"
}
#IBAction func ResetButton(_ sender: Any) {
self.myTimer.invalidate()
theValue = 0
self.textLabel.text = String(theValue)
}
#IBAction func PauseButton(_ sender: Any) {
self.myTimer.invalidate()
}
#IBAction func PlayButton(_ sender: Any) {
self.myTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateMyLabel), userInfo: nil, repeats: true)
}
}
This is all the code I have right now. As you can probably tell I'm new too StackExchange and so please excuse any breach in etiquette.
it's giving an error because you forgot to add else part in your code.
func randomText() -> String {
if theValue > 5 {
let words = ["Place", "Cat", "House"]
return words.randomElement() ?? "" //Use default method to get random element from Array
}
return "string if theValue < 5 or equal to 5"
}
I am trying to input information in a textfield and then store the information that is typed out as a variable, to be used in a string. For some reason it crashes whenever I click on the next textfield after the first, or the third after the second. Here is what I have.
var name: String?
#IBAction func nameField(name: UITextField) {
let name = name.text
}
var contact: String?
#IBAction func contactField(contact: UITextField) {
let contact = contact.text
}
var other: String = "nothing"
#IBAction func otherField(other: UITextField) {
if other == nil {
}else{
let other = other.text!
}
}
Here's my code for my calculator and it works fine!
import UIKit
class ViewController: UIViewController {
var number1 = 0
var number2 = 0
var operation = 0
#IBOutlet var screen: UILabel!
#IBAction func Onebutton(sender: AnyObject) {
addNumber(1)
}
#IBAction func Twobutton(sender: AnyObject) {
addNumber(2)
}
#IBAction func Threebutton(sender: AnyObject) {
addNumber(3)
}
#IBAction func Fourbutton(sender: AnyObject) {
addNumber(4)
}
#IBAction func Fivebutton(sender: AnyObject) {
addNumber(5)
}
#IBAction func Sixbutton(sender: AnyObject) {
addNumber(6)
}
#IBAction func Sevenbutton(sender: AnyObject) {
addNumber(7)
}
#IBAction func Eightbutton(sender: AnyObject) {
addNumber(8)
}
#IBAction func Ninebutton(sender: AnyObject) {
addNumber(9)
}
#IBAction func Zerobutton(sender: AnyObject) {
addNumber(0)
}
#IBAction func Multiplybutton(sender: AnyObject) {
operation = 1
}
#IBAction func Dividebutton(sender: AnyObject) {
operation = 2
}
#IBAction func Addbutton(sender: AnyObject) {
operation = 3
}
#IBAction func Subtractbutton(sender: AnyObject) {
operation = 4
}
#IBAction func Equalsbutton(sender: AnyObject) {
switch operation{
case 1: screen.text = String (number1*number2)
case 2: screen.text = String (number1/number2)
case 3: screen.text = String (number1+number2)
case 4: screen.text = String (number1-number2)
default: println()
}
}
#IBAction func clearbutton(sender: AnyObject) {
number1 = 0
number2 = 0
operation = 0
screen.text = "0"
}
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.
}
func addNumber (pushButton : Int){
if operation == 0 {
number1 = number1*10+pushButton
screen.text = String (number1)
} else {
number2 = number2*10+pushButton
screen.text = String (number2)
}
}
}
But I want to make the calculator calculate in decimal form and not round off to the nearest number.
Use floats.
var number: Float = 0
number = number + 0.1
println(number)
//0.1 should be printed.
You are currently basically saying:
var number: Int = 0
This is pretty much how the computer reads it; number is an integer. To make it so that number can be a decimal (float), you have to say:
var number: Float = 0