Trying to pass Doubles from a view to an another but it doesn't work - swift

Hey I'm a newbie to Swift and Xcode and I am trying to make a little app but I have an error and can't fix it.
I'm trying to passe a double from a view to another but it says
Binary operator '+=' cannot be applied to operands of type 'String' and "int"
That's my first view :
#IBOutlet weak var Rned: UILabel!
var ArgentC: Double = 0
override func viewDidLoad() {
super.viewDidLoad()
Rned.text = String(ArgentC)
Rned.backgroundColor = UIColor(patternImage: UIImage(named: "Rectangle2")!)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let SecondViewController = segue.destination as! SacocheVCp2
SecondViewController.ArgentCV = Rned.text!
}
#IBAction func Reset(_ sender: Any) {
Rned.text = String(0)
ArgentC = 0
}
#IBAction func CashButton(_ sender: Any) {
performSegue(withIdentifier: "segueSac", sender: self)
}
and that is my second view with the error, and the error appears when I want to add numbers to my doubles.
#IBOutlet weak var Rend2Label: UILabel!
var ArgentCV = String()
override func viewDidLoad() {
super.viewDidLoad()
Rend2Label.backgroundColor = UIColor(patternImage: UIImage(named: "Label")!)
Rend2Label.text = ArgentCV
// Do any additional setup after loading the view.
}
#IBAction func CinqEur(_ sender: Any) {
ArgentCV += 5 // <== Here
Rend2Label.text = ArgentCV
}
#IBAction func DixEur(_ sender: Any) {
ArgentCV += 10 // <== Here
}
#IBAction func VingtEur(_ sender: Any) {
ArgentCV += 20 // <== Here
}
#IBAction func CinquanteEur(_ sender: Any) {
ArgentCV += 50 // <== Here
}
Thanks for your time.

You don't have to send it as a String , you can send it as Int
secondViewController.argentCV = Int(rned.text) ?? 0 // ?? to avoid crashes but make sure it doesn't destroy logic
Then inside SacocheVCp2
var argentCV = 0 // 0 is default
Finally
argentCV += 5 // <== Here
rend2Label.text = "\(argentCV)"

Related

ViewController doesn't pass data on completion

I have 2 ViewControllers.
TimerViewController passes a variable to the EditTimerViewConroller. EditTimerViewConroller edits it and should pass it back, but it looks like code in .completion is not executed.
Any advice how to fix it?
My code is:
TimerViewController
import UIKit
import AVFoundation //play sounds
class TimerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var player: AVAudioPlayer!
var timer = Timer()
var totalTime = 10.0
var secondsRemaining = 10.0
var secondsPassed = 0.0
let timerStep = 0.1
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var progressBar: UIProgressView!
#IBAction func startPressed(_ sender: UIButton) {
//works fine
}
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
let editTimer = EditTimerViewController()
editTimer.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \(self?.totalTime)")
}
}
}
func playSound(fileName: String) {
//works fine
}
#objc func updateTimer() {
//works fine
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(totalTime)
print("Pasing duration = \(totalTime) to Edit screen")
}
}
EditTimerViewController
import UIKit
class EditTimerViewController: UIViewController {
let maxDuration = 60
var duration: Int? //timer duraton is passed from Timer
public var completion: ((Int?) -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
durationSlider.minimumValue = 0
durationSlider.maximumValue = Float(maxDuration)
durationSlider.value = Float(duration!)
durationLabel.text = String(duration!) + "s"
}
#IBOutlet weak var durationLabel: UILabel!
#IBOutlet weak var durationSlider: UISlider!
#IBAction func durationSliderChanged(_ sender: UISlider) {
duration = Int(sender.value)
print(duration!)
durationLabel.text = String(duration!) + "s"
}
#IBAction func cancelPressed(_ sender: UIButton) {
print("Cancel pressed, dismissing Edit screen")
self.dismiss(animated: true, completion: nil)
}
#IBAction func savePressed(_ sender: UIButton) {
print("Save pressed, duration is \(duration!)")
completion?(duration!)
self.dismiss(animated: true, completion: nil)
}
}
In the output after pressing Save button I see
Save pressed, duration is 11
but after it there is no sign of
editTimer completed, totalTime now is 11
and timer duration never changes
Change
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
let editTimer = EditTimerViewController()
editTimer.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \(self?.totalTime)")
}
}
}
To
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
}
And move completion inside prepare
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(totalTime)
print("Pasing duration = \(totalTime) to Edit screen")
destinationVC.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \ (self?.totalTime)")
}
}
}
}

How can I make variables inside an IBAction public to all view controllers?

So I'm trying to make a Chess Time app, where both players have access to a clock and they change the time between bullet(3minutes), Blitz(5minutes), and Rapid(10Minutes). Well in my second view controller SettingsController I made 3 IBActions UIButtons for this.
#IBAction func bulletPressed(_ sender: UIButton) {
var storedTime = bullet
self.delegate?.storedTimeTimer()
self.navigationController?.popViewController(animated: true)
}
#IBAction func blitzPressed(_ sender: UIButton) {
var storedTime = blitz
}
#IBAction func rapidPressed(_ sender: UIButton) {
var storedTime = rapid
}
This is my SettingsController, my whole point is trying to get the storedTime into the first controller. I tried to use a delegate, but I couldn't get it to work.
Here is the full First Controller:
import UIKit
class ChessTimer: UIViewController {
#IBOutlet weak var playerTimer1: UILabel!
#IBOutlet weak var playerTimer2: UILabel!
var timer = Timer()
var time = 10
var isTimerRunning = false
override func viewDidLoad() {
super.viewDidLoad()
if isTimerRunning == false {
runTimer()
}
}
#IBAction func restartButton(_ sender: UIButton) {
}
#IBAction func pausePressed(_ sender: UIButton) {
timer.invalidate()
}
#IBAction func settingsPressed(_ sender: UIButton) {
performSegue(withIdentifier: "goToSettings", sender: self)
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self,selector:
(#selector(ChessTimer.updateTimer)),userInfo: nil, repeats: true)
isTimerRunning = true
}
#objc func updateTimer() {
if storedTime! < 1 {
timer.invalidate()
playerTimer1.text = "00:00"
playerTimer2.text = "00:00"
}
else {
storedTime! -= 1
playerTimer1.text = prodTimeString(time: TimeInterval(storedTime)!)
}
}
func prodTimeString(time: TimeInterval) -> String {
let prodMinutes = Int(time) / 60 % 60
let prodSeconds = Int(time) % 60
return String(format: "%02d:%02d", prodMinutes, prodSeconds)
}
#IBAction func playerButton1(_ sender: UIButton) {
}
#IBAction func playerButton2(_ sender: UIButton) {
}
}
extension ChessTimer: SettingsControllerDelegate {
func storedTimeTimer() {
}
}
This is the second full controller
import UIKit
class SettingsController: UIViewController {
var bullet = "03:00"
var blitz = "05:00"
var rapid = "10:00"
var storedTime = 0
var delegate: SettingsControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func bulletPressed(_ sender: UIButton) {
var storedTime = bullet
self.delegate?.storedTimeTimer()
self.navigationController?.popViewController(animated: true)
}
#IBAction func blitzPressed(_ sender: UIButton) {
var storedTime = blitz
}
#IBAction func rapidPressed(_ sender: UIButton) {
var storedTime = rapid
}
}
protocol SettingsControllerDelegate {
func storedTimeTimer()
}
This can be achieved using a Constants.swift file.
Click File -> New -> File -> Swift File and then name it Constants.swift.
In Constants.swift, declare var storedTime = 0.
Delete var storedTime = 0 from your view controllers, you'll only need it in Constants.swift. (So delete it from SettingsController, etc.)
The storedTime variable will now be public to all view controllers. 👍
Hope this helps someone!

Swift Character Count

I'm new to xcode, need to find the character count of the String in the UILabel
#IBAction func buttonPressed(_ sender: Any) {
curr_channel.text = ""
let tag = (sender as! UIButton).tag
if((curr_channel.text?.character.count())! < 2){
curr_channel.text = curr_channel.text! + String(tag)
}
}
I guess this is what you need :
#IBAction func buttonPressed(_ sender: Any) {
let tag = (sender as! UIButton).tag
if let text = curr_channel.text, text.count < 2 {
curr_channel.text = "\(text) \(tag)"
}
}
Here's how you can print/ get the character count in a UILable.
#IBOutlet weak var myLabel: UILabel!
#IBAction func buttonPressed(_ sender: Any) {
let countOfCharsInLabel = myLabel.text?.count
print("\(countOfCharsInLabel)")
}

View Controller doesn't find a func member

I'm getting this error:
Value of type 'DiscountVC' has no member 'calculateTotal'. And I have no clue why. Basically, I'm trying to make this calculator:
It should work as soon as you insert any value on the discountTF. Also, I have some pre-discounted buttons that just edit the discount value. The subtotalLabel value comes from another ViewController. For testing purposes, I'm using an initial value of 999.9.
import UIKit
class DiscountVC: UIViewController {
#IBOutlet var numericKeyboardView: UIView!
#IBOutlet var subtotalLabel: UILabel!
#IBOutlet var discountTF: UITextField!
#IBOutlet var totalLabel: UILabel!
var subtotal : Double = 999.9
var discount : Double = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
addKeyboard(view: numericKeyboardView)
subtotal = 999.9
discount = 0.0
discountTF.addTarget(self, action: #selector(self.calculateTotal(_:)), for: UIControl.Event.editingChanged)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
func calculateTotal() {
let totalDouble = Double(subtotal) - Double(discountTF.text!)!
totalLabel.text = String(totalDouble)
}
func addKeyboard(view: UIView) {
let numericKeyboard = KeyboardVC(nibName: "NumericKeyboardVC", bundle: nil)
view.addSubview(numericKeyboard.view)
addChild(numericKeyboard)
}
#IBAction func fivePercentedButtonPressed(_ sender: Any) {
discount = Double(discountTF.text!)! * 0.05
discountTF.text = "\(discount)"
print(discount)
}
#IBAction func tenPercentButtonPressed(_ sender: Any) {
discount = Double(discountTF.text!)! * 0.1
discountTF.text = "\(discount)"
print(discount)
}
#IBAction func fifteenPercentButtonPressed(_ sender: Any) {
discount = Double(discountTF.text!)! * 0.15
discountTF.text = "\(discount)"
print(discount)
}
#IBAction func twentyPercentButtonPressed(_ sender: Any) {
discount = Double(discountTF.text!)! * 0.2
discountTF.text = "\(discount)"
print(discount)
}
#IBAction func goButton(_ sender: Any) {
}
}
Change to
#objc func calculateTotal(_ tex:UITextField){ --- }

Passing Data through 3 view Controllers [Swift 3.0 - Xcode]

Im passing data through 3 VCs, so in the end I want to achieve sending data from the third VC to the first. I send Data from V2 to V3 with a segue and then send it back from V3 to V2 by delegate. Im then trying to send it from V2 to V1 through a segue but I cant seem to collect the data (sent back from V3) in V2 to then send to V1.
The data from V3 doesn't show up in V1, but the code still runs.
Can anyone help?
heres my code from V2 and V3:
V2:
import UIKit
class SecondViewController: UIViewController, thirdDelegate {
var GetBack: String?
var SendForward = [String]()
var Datacollect = [String]()
var Collect = [String]()
let ct = "Conner#2"
let new = "All#2"
#IBOutlet var Hinput: UITextField!
#IBOutlet var Ninput: UITextField!
#IBAction func MAP(_ sender: Any) {
if Hinput.text != ""{
performSegue(withIdentifier: "SegueSearch", sender: self)}
}
#IBAction func Info(_ sender: Any) {
performSegue(withIdentifier: "SegueInfo", sender: self)
}
func DataToPass(ArrayName: [String]) { //function from delegate
Datacollect = ArrayName
print(ArrayName)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "SegueSearch"{
let thirdController = segue.destination as! ThirdViewController
SendForward.append(Hinput.text!)
SendForward.append(ct)
thirdController.height = SendForward
thirdController.delegate = self
} else if segue.identifier == "SegueInfo" {
let firstController = segue.destination as! ViewController
if Datacollect.count != 0{
Collect.append(Datacollect[1])
Collect.append(Datacollect[0])}
Collect.append(Ninput.text!)
Collect.append(new)
firstController.AllData = Collect
}
}
override func viewDidLoad() {
super.viewDidLoad()
print("check",Datacollect)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Is this the part that isn't working?
func DataToPass(ArrayName: [String]) {
Datacollect = ArrayName
print(ArrayName)
}
V3:
import UIKit
protocol thirdDelegate{
func DataToPass (ArrayName: [String])
}
class ThirdViewController: UIViewController {
var height = [String]()
var SendBack = [String]()
let ko = "Keith#3"
var delegate: thirdDelegate! = nil
#IBOutlet var Houtput: UILabel!
#IBAction func Home(_ sender: Any) {
let StrH = String(height[0])
SendBack.append(ko)
SendBack.append(StrH!)
delegate.DataToPass(ArrayName: SendBack)
}
override func viewDidLoad() {
Houtput.text = height[0]
super.viewDidLoad()
print(height)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}