1

I am currently experiencing difficulties in the development of my app. To make it simple, it is an application that allows you to do mental calculation.

My problem is with the display of the calculations that have been proposed, the results provided by the player, and the result of the calculation. In fact, when the program knows that there is no more calculation to propose it launches in the "case 2" of a function that contains a for loop that calls a CreatLabelJuste() function if the result provided by the player is correct, and a CreatLabelFAux() function if the calculation is wrong.

These functions create labels. It works pretty well. The problem is that to restart a game, I call the viewDidLoad() function which resets my game. But when the labels have to be recreated the old ones haven't removed themselves from the view that contains them!

I don't know if it's clear enough, but if someone knows if it's possible to "destroy" these labels, so that when the game starts again, in the end nothing overlaps.

func creatLabelJuste(TagX : Int) {
    let labelJ = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    let labelForAnswerJ =  UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    let  labelForResultJ =  UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))

    switch TagX {
    case 0 :
        labelJ.font = UIFont(name: "futura", size: 20)
        labelJ.center = CGPoint(x: 96, y: yAxis)
        labelJ.textAlignment = .center
        labelJ.text = "\(memoriseCalcule[compter])³"

        self.myView.addSubview(labelJ)

        labelForAnswerJ.font = UIFont(name: "futura", size: 20)
        labelForAnswerJ.center = CGPoint(x: 187, y: yAxis)
        labelForAnswerJ.textAlignment = .center

        labelForAnswerJ.text = "\(memoriseAnswer[compter])"
        self.myView.addSubview(labelForAnswerJ)

        labelForResultJ.font = UIFont(name: "futura", size: 20)
        labelForResultJ.center = CGPoint(x: 278, y: yAxis)
        labelForResultJ.textAlignment = .center
        labelForResultJ.text = "\(memoriseResult[compter])"
        self.myView.addSubview(labelForResultJ)
    //      print("/////////////////////////////////////CreateLabelJuste : LabelJ = \(labelJ.text)/ laberForAwnswerJ = \(labelForAnswerJ.text!)/ labelforResultJ+ = \(labelForResultJ.text) ////////////////////////////////////////////")
    case 1 :
        self.myView.removeFromSuperview()
    default :
        print("defaut")
    }
}

func creatLabelFaux(Tag : Int) {
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    let labelForAnswer =  UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    let labelForResult =  UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    label.text = ""
    labelForResult.text = ""
    labelForAnswer.text = ""

    switch Tag {
    case 0:
        label.font = UIFont(name: "futura", size: 20)
        label.center = CGPoint(x: 96, y: yAxis)
        label.textAlignment = .center
        label.text = "\(memoriseCalcule[compter])³"
        label.backgroundColor = UIColor(red: 238/255, green: 105/255, blue: 86/255, alpha: 1)
        label.layer.cornerRadius = 10
        label.clipsToBounds = true
        self.myView.addSubview(label)

        labelForAnswer.font = UIFont(name: "futura", size: 20)
        labelForAnswer.center = CGPoint(x: 187, y: yAxis)
        labelForAnswer.textAlignment = .center
        labelForAnswer.backgroundColor = UIColor(red: 238/255, green: 105/255, blue: 86/255, alpha: 1)
        labelForAnswer.text = "\(memoriseAnswer[compter])"

        self.myView.addSubview(labelForAnswer)

        labelForResult.font = UIFont(name: "futura", size: 20)
        labelForResult.center = CGPoint(x: 278, y: yAxis)
        labelForResult.textAlignment = .center
        labelForResult.backgroundColor = UIColor(red: 238/255, green: 105/255, blue: 86/255, alpha: 1)
        labelForResult.text = "\(memoriseResult[compter])"
        labelForResult.layer.cornerRadius = 10
        labelForResult.clipsToBounds = true
        self.myView.addSubview(labelForResult)
    case 1 :
        //  label.delete(true)
        //labelForAnswer.delete(true)
        //labelForResult.delete(true)
        self.myView.removeFromSuperview()
    default:
        print("merde")
    }
}

for _ in 0..<setLimite{
    yAxis = yAxis + 30

    if memoriseAnswer[compter] == memoriseResult[compter]{
        creatLabelJuste(TagX: 0)
    } else {//if memoriseAnswer[compter] != memoriseResult[compter] {
        creatLabelFaux(Tag: 0)
    }

    compter = compter + 1
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Henri Piot
  • 31
  • 5
  • 1
    Never call `viewDidLoad` yourself. – rmaddy Sep 07 '18 at 18:27
  • Have you tried to move the code out of the `viewDidLoad` into a method and call that one instead? `viewDidLoad` is going to be handle for the navigation strategy you have implemented (whether it's a _NavigationController_ or a _TabController_) and act properly. – Mauricio Chirino Sep 07 '18 at 19:17
  • Hi , I call the viewed load in my "replay" button ? this is not correct ? all of my code is on other func – Henri Piot Sep 07 '18 at 20:38

1 Answers1

0

You need to keep the reference to the label in the class instead of function. So you will be able to use

.removeFromSuperview() to remove the label like you are doing here:

self.myView.removeFromSuperview()

Something like this:

var labelJ: UILabel!
var labelForAnswerJ: UILabel!
var  labelForResultJ: UILabel!

func creatLabelJuste(TagX : Int) {
    labelJ = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    labelForAnswerJ = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    labelForResultJ = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    ...
    ...
    ...
}

Also if you are calling viewDidLoad() manually - it's not a good way

just add some new function with your game restart logic and call it from viewDidLoad()

and when you need to restart the game just call this function instead of viewDidLoad() also add label.removeFromSuperview() for each label that needs to be removed

And call restart() when you need to restart the game

change your code to this, replace myView initialization also change viewDidLoad() and Replay(). Add reset() function

var myView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    reset()
}

func reset() {
     myView = UIView(frame: (CGRect(x: 0, y: 200, width: 375, height: 400)))

    self.enterTextField.becomeFirstResponder()

    // is Hidden ppt
    ReplayBtn.isHidden = true
    goBackBtn.isHidden = true
    enterTextField.isHidden = false
    nextBtn.isHidden = false

    // set variables to 0
    numberToCube = 0
    result = 0
    resultFromUser = ""
    lenghtAnswer = 0
    stats = 0
    score = 0
    limite = 0
    scoreLbl.text = ""
    displayNumberLbl.text = ""
    displayResultLbl.text = ""
    displayAnswerLbl.text = ""
    memoriseCalcule.removeAll()
    memoriseAnswer.removeAll()
    memoriseResult.removeAll()
    ListeNombre = "Asked :\n"
    ListeAnswer = "Answer :\n"
    ListeCanswer = "Correct :\n"
    yAxis = 50

    compter = 0

    // Label Manager
    scoreLbl.textColor = UIColor.black
    NumberLbl.textColor = UIColor.black
    scoreLbl.textAlignment = NSTextAlignment.center
    self.NumberLbl.frame = CGRect(x: 26, y: 100, width: 322, height: (50))
    self.scoreLbl.frame = CGRect(x: 26, y: 180, width: 322, height: (50))
    NumberLbl.textColor = UIColor.white
    // Launch func

    number()
}

@IBAction func Replay(_ sender: Any) {
    LabelJ.removeFromSuperview()
    labelForAnswerJ.removeFromSuperview()
    labelForResultJ.removeFromSuperview()

    reset()
    creatLabelFaux(Tag: 1)
    creatLabelJuste(TagX: 1)
}
Kostia M
  • 16
  • 2
  • Ok i see, seems logic, I'll try this and I'll let you know ! but thank you anyway for your answer ! ;) – Henri Piot Sep 07 '18 at 20:36
  • Hi, I tried to declare labels in the class but the problem remains the same : when I finish the game for the 2nd time, the labels overlap.. by removing them from the view they just disappear but they are not "clear" – Henri Piot Sep 07 '18 at 21:41
  • @HenriPiot actually you can do whatever you want in restart - also clear labels. (change text, color, etc). Or recreate them in restart ( set default values ~ clear them) – Kostia M Sep 08 '18 at 07:05
  • are you clearing `myView` ? It should be very simple logic issue. Just check how you are recreating you view hierarchy. Check this video. It might help you to debug visually. https://developer.apple.com/videos/play/wwdc2016/410/ – Kostia M Sep 08 '18 at 07:09
  • i want them to be cleared, you will easily see this in the 3D pic I post ! – Henri Piot Sep 08 '18 at 08:25
  • @HenriPiot I have edited my answer. Please try to apply that changes. – Kostia M Sep 08 '18 at 08:52
  • M WOW it works perfectly !!!!! thank you so much ! your the beast !! btw why call viewdidload directly is incorect ??? – Henri Piot Sep 08 '18 at 09:11
  • @HenriPiot it's part of viewController lifecycle. You shouldn't call it manually to prevent unpredictable UI behavior. You can read more here https://developer.apple.com/documentation/uikit/uiviewcontroller – Kostia M Sep 08 '18 at 09:41