-1

newbie swift programmer here that needs help with something that probably is trivial...

This is in different File, different View:

class CanvasContainerView: UIView {
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
   
    // here are all of the calculations that lead to scoreString being calculated..

        var scoreString = round(1000 * accuracyTotal / angleTotal)
        }
//lots of other code
}

I need the value of my calculated "scoreString" to be accessible in a different file, different controller. How can i pass this value through if i'm using TouchesMoved function ? Below is how i tried to implement it in different file but failed miserably as there is no "scoreString" in scope:

import UIKit

class CanvasMainViewController: UIViewController {

    @IBOutlet weak var ScoreText: UITextField!
 
    /// Prepare the drawing canvas.
    /// - Tag: CanvasMainViewController-viewDidLoad
    override func viewDidLoad() {
        
        super.viewDidLoad()
        ScoreText.text = "\(CanvasContainerView.touchesMoved(scoreString))"
}
//lots of code
}

In the end i want my score to be displayed on top of the screen: enter image description here

So i am aware that there are questions like this already on Stack but whats specific about my question is that im using this "touchesMoved" overriden function that doesn't let me return any value. It shouts it needs void return type.

I will be very thankful for any help.

NDCoder
  • 93
  • 2
  • 8
  • Add the controller as a delegate in container view, so that when view detect touches it can call the delegate passing it the score string. The the delegate method called can update the text field. – Ptit Xav Mar 28 '22 at 06:04

2 Answers2

1

Using a delegate is the good method :

// the protocol (ie the method called by container view in the controller)
protocol CanvasContainerViewDelegate {
    func scoreUpdate(fromView view:CanvasContainerView, newScore: Double)
}

class CanvasContainerView: UIView {
    // the delegate that will be called
    var delegate: CanvasContainerViewDelegate?
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
   
    // here are all of the calculations that lead to scoreString being calculated..

        var scoreString = round(1000 * accuracyTotal / angleTotal)
        // Telling the delegate the new score value
        delegate?.scoreUpdate(fromView: self, newScore: scoreString)
        }
//lots of other code
}

class CanvasMainViewController: UIViewController, CanvasContainerViewDelegate {
    
    @IBOutlet weak var ScoreText: UITextField!
    @IBOutlet weak var containerView: CanvasContainerView!
    
    /// Prepare the drawing canvas.
    /// - Tag: CanvasMainViewController-viewDidLoad
    override func viewDidLoad() {
        
        super.viewDidLoad()
        // set the controller as a delegate of the view
        containerView.delegate = self
    }
    
    // Update the score (called by the view)
    func scoreUpdate(fromView view: CanvasContainerView, newScore: Double) {
        ScoreText.text = "\(newScore)"
    }
    
    
    //lots of code
}
Ptit Xav
  • 3,006
  • 2
  • 6
  • 15
  • This is the kind of an answer that i was looking for. Thank you very much! A professional way of dealing with this situation, cause my "public" way is just a worse, less safe way of doing so. Thank you! – Patryk Piwowarczyk Mar 28 '22 at 14:01
  • One more question: "containerView.delegate = self" crashes the app on launch with code: Thread 1: EXC_BAD_ACCESS (code=2, address=0x22594cd60). Is it possible that i've implemented your answer code wrong or should I add something more? – Patryk Piwowarczyk Mar 28 '22 at 14:39
  • @PatrykPiwowarczyk : you need to be sure that container view is initialised before using it. I assumed it was created in storyboard. The delegate assignment can also be done in storyboard. – Ptit Xav Mar 28 '22 at 17:45
0

Apparently adding public in front of the var declared on top of the file solved the problem. Thank you for participation in trying to help me.