18 Replies
      Latest reply on Feb 11, 2019 3:11 PM by Claude31
      chuba Level 1 Level 1 (0 points)

        Hallo, i have main view conrtoller class, I would like to start the function in other UIview class.

        When i make it "static func..." = there is an error - Instance member 'view' cannot be used on type 'BattleViewController'.

        Thank You for help.

         

        func setGameOverInfo() {

                let gameOver = UILabel()

                gameOver.text = "Game over\n" + "Your score: " + BattleViewController.updatedScore()

                gameOver.numberOfLines = 2

                gameOver.font = UIFont.systemFont(ofSize: 24)

                gameOver.textColor = UIColor.white

                gameOver.textAlignment = .center

             

                view.addSubview(gameOver)

                gameOver.translatesAutoresizingMaskIntoConstraints = false

             

                let centerXGOConstraint = NSLayoutConstraint(item: gameOver, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)

                let centerYGOConstraint = NSLayoutConstraint(item: gameOver, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: -20 * scale)

             

                view.addConstraints([centerXGOConstraint, centerYGOConstraint])

            }

        • Re: make static function that brings UILabel
          Claude31 Level 8 Level 8 (6,365 points)

          What do you mean by "start function in other class" ?

           

          Do you mean call this func from another class ?

          Is the UIView inside the mainViewController ?

          Or is it in a different UIViewController ? I understand this is the case with BattleViewController.

           

          Then, where are you going to see the UILabel created in setGameOver ?

          Why do you create a new label eaxh time you call ?

           

          Anyway, to call a func from another class, the best is to use delegation.

           

          Are you familiar with it ?

          If not, have a look here: https://forums.developer.apple.com/thread/111569

            • Re: make static function that brings UILabel
              chuba Level 1 Level 1 (0 points)

              Yes, to call this function.

              I have view controller callled BattleViewController, which is the one and only.

              In that viewcontroller I call UIView classes - Missile and Alien. Instances of both of them are prepared from BattleViewController, for example with "FIRE"  button. It works.

              I have the method prepared in Missile class - called hitCheck() - it tries when there is a collision of missile object and alien object. It is just like collision indicator in every instance of missile. In case of collision - missile and alien disappear, and it works ok.

              After that I would like to call in my VController anoter UIView - little animation of the explosion. I have the UIView class named Explosion. I would like to call this UIView just strictly connected with hitCheck().

              I am sorry, I have paste wrong part of code - but there is a simmilar problem - in cse of collision my ship with an alien - i want to call setGameOver() method from Alien.class - to run in ViewController.

              Shortly - how to call in UIView method from ViewController. If I make functin static - it causes an error.

               

              With gameOver is simple - with segue. But how with an explosion?

               

              Thank You for help.

              • Re: make static function that brings UILabel
                chuba Level 1 Level 1 (0 points)

                Would You be so nice to give some kind of reply?

                  • Re: make static function that brings UILabel
                    Claude31 Level 8 Level 8 (6,365 points)

                    Why do you declare the func static ? If I understand your code, it is related to the instance, not to the class.

                     

                    To make sure I understand correctly:

                    - the viewController is BattleField

                    - inside you have a func named setGameOver()

                    - You have a Missile subclass of UIViews for your missiles and aliens

                    - In the BattleField Controller, you declared instances of Missiles and Aliens, like

                         var missile1 = Missile()          // Maybe with some parapeters

                     

                    - When there is a hitCheck, you want to call setGameOver from the missile

                     

                    You have several ways to know which is the viewController (parent) and then call

                    parentVC?.setGameOver()

                    First :

                    - declare a property in Missile and Aliens to keep a reference of the viewController (BattleField)

                    var parentVC : UIViewController?

                    set its value to the right controller (self if you do it when you create the missile instance in BattleField)

                     

                    Second

                    Creeate an extension of UIView to search for this parentVC (see https://stackoverflow.com/questions/1372977/given-a-view-how-do-i-get-its-viewcontroller)

                    extension UIView {
                        var parentViewController: UIViewController? {
                            var parentResponder: UIResponder? = self
                            while parentResponder != nil {
                                parentResponder = parentResponder!.next
                                if let viewController = parentResponder as? UIViewController {
                                    return viewController
                                }
                            }
                            return nil
                        }
                    }
                      • Re: make static function that brings UILabel
                        chuba Level 1 Level 1 (0 points)

                        - the viewController is BattleField - YES

                        - inside you have a func named setGameOver() - YES

                        - You have a Missile subclass of UIViews for your missiles and aliens - YES, I have missiles and aliens flying in BattleViewController

                        - In the BattleField Controller, you declared instances of Missiles and Aliens, like

                             var missile1 = Missile()          // Maybe with some parapeters YES

                         

                        - When there is a hitCheck, you want to call setGameOver from the missile - NOT EXACTLY - I have two different cases and I am sorry that i have mixed it earlier. I have two cases, and understand that is really the same probem - how to realise method in UIViewController (like presenting UILabel with score after when the game is over - 1st case, presenting animation in UIVController after collision of two UIView objects - 2nd case) and call it inside of UIView.

                         

                        1st case - I want to call startExplosion method in instance of Explosion.class - which should be a seprate animation after hitCheck (when missile reach alien, they both disappear and in that place appears explosion) and...hitCheck is written in Missile.class

                        2nd case - I want to call setGameOver method which is written in BattleViewController. And it should be called from the method CollisionCheck, which is written in Alien.class (and it indicates if alien has reached my ship...),

                         

                        I amsorry but i do not really know how to finish it...

                        class Missile: UIView {

                         

                            let screenSettings = ScreenSettings()

                            let missileStep = 4

                            let missileInterval: Double = 0.02

                         

                            var missileTimer = Timer()

                            var missileCounter: Int = 17

                            var missileX: CGFloat!

                            var missileY: CGFloat = BattleViewController.dimXY

                         

                            var parentVC: UIViewController?     //right?

                         

                            func hitCheck() {

                                for oneMissile in BattleField.missiles {

                                    for oneAlien in BattleField.aliens {

                                        if oneAlien.getAlienX() - oneMissile.getMissileX() <= 14 && oneAlien.getAlienX() - oneMissile.getMissileX() >= -14 && oneAlien.getAlienyY() - oneMissile.getMissileY() <= 5 && oneAlien.getAlienyY() - oneMissile.getMissileY() >= -5 {

                        parentVC = BattleViewController()          //right? I am not sure...

                                            if oneAlien.makesGameOver() {

                                           parentVC?.setGameOver() //here? It does not work, I cannot call it like this...

                                                BattleViewController.score += 10

                                                BattleViewController.scoreLabel.text = "Score: " + String(BattleViewController.score)

                                            }

                                            oneMissile.stopMissile()

                                            oneAlien.stopAlien()

                                        }

                                    }

                                }

                            }

                         

                        }

                         

                        I do not really understand how to manage the parent view controller, probably it is simple... but I do not know how to write it properly...

                        Thanks for help and patience, I am still learning with full of pain and frustration, but it is really better than few months ago...

                          • Re: make static function that brings UILabel
                            Claude31 Level 8 Level 8 (6,365 points)

                            No, that's not where you have to define parent.

                             

                            Could you show the code where you create objects (missiles or aliens) ? That is not inside the subclass but inside BattleFieldController

                             

                            At this place where you create missile (or alien), add the line

                            parentVC = self (which is BattleField)

                            Then, in hitCheck(), you can call

                             

                            parentVC?.setGameOver()

                             

                            I do not see how you define BattleFieldController, but I suspect score is one of its properties and scoreLabel one of its IBOutlets.

                            If so, you should replace

                                                    BattleViewController.score += 10
                                                    BattleViewController.scoreLabel.text = "Score: " + String(BattleViewController.score)

                            with

                                                    parentVC?.score += 10
                                                    parentVC?.scoreLabel.text = "Score: " + String(parentVC?.score)

                            So, your class will be

                             

                            class Missile: UIView {
                            
                                let screenSettings = ScreenSettings()
                                let missileStep = 4
                                let missileInterval: Double = 0.02
                            
                                var missileTimer = Timer()
                                var missileCounter: Int = 17
                                var missileX: CGFloat!
                                var missileY: CGFloat = BattleViewController.dimXY
                            
                                var parentVC: UIViewController?
                            
                                func hitCheck() {
                                    for oneMissile in BattleField.missiles {
                                        for oneAlien in BattleField.aliens {
                                            if oneAlien.getAlienX() - oneMissile.getMissileX() <= 14 && 
                                                oneAlien.getAlienX() - oneMissile.getMissileX() >= -14 &&
                                                oneAlien.getAlienyY() - oneMissile.getMissileY() <= 5 && 
                                                oneAlien.getAlienyY() - oneMissile.getMissileY() >= -5 {
                            
                                                if oneAlien.makesGameOver() {
                                                    parentVC?.setGameOver() //. here? It does not work, I cannot call it like this...
                                                    parentVC?.score += 10
                                                    parentVC?.scoreLabel.text = "Score: " + String(parentVC?.score)
                                                }
                                                oneMissile.stopMissile()
                                                oneAlien.stopAlien()
                                            }
                                        }
                                    }
                                }
                            
                            }
                              • Re: make static function that brings UILabel
                                chuba Level 1 Level 1 (0 points)

                                class Alien: UIView {

                                  

                                    let screenSettings = ScreenSettings()

                                  

                                    var alienTimer = Timer()

                                    var alienCounter: Int = 0

                                    var alienX: CGFloat!

                                    var alienY: CGFloat = 0

                                  

                                    override init(frame: CGRect) {

                                        super.init(frame: frame)

                                        self.backgroundColor = UIColor.clear

                                    }

                                  

                                    required init?(coder aDecoder: NSCoder) {

                                        fatalError("init(coder:) has not been implemented")

                                    }

                                  

                                    static func setAlienRange() -> CGFloat {

                                        return 8

                                    }

                                  

                                    func setAlien(x: CGFloat, y: CGFloat) {

                                        let scale = screenSettings.minimalScaleFactor()

                                        let alienArc = UIBezierPath(arcCenter: CGPoint(x: x * scale, y: y * scale), radius: Alien.setAlienRange() * scale, startAngle: 0.06 * .pi, endAngle: 0.94 * .pi, clockwise: true)

                                        alienArc.lineWidth = BattleViewController.lineWidth * scale

                                        UIColor(red: 0.93, green: 0.93, blue: 0.93, alpha: 1).setStroke()

                                        alienArc.stroke()

                                      

                                        let alienLine = UIBezierPath()

                                        alienLine.move(to: CGPoint(x: (x - 2) * scale, y: (y + 10) * scale))

                                        alienLine.addLine(to: CGPoint(x: (x - 4) * scale, y: y - 4 * scale))

                                        alienLine.move(to: CGPoint(x: (x + 2) * scale, y: (y + 10) * scale))

                                        alienLine.addLine(to: CGPoint(x: (x + 4) * scale, y: y - 4 * scale))

                                      

                                        UIColor(red: 0.4, green: 0.6, blue: 1, alpha: 1).setStroke()

                                 

                                        alienLine.lineWidth = BattleViewController.lineWidth * scale

                                        alienLine.stroke()

                                    }

                                  

                                    override func draw(_ rect: CGRect) {

                                        setAlien(x: alienX, y: alienY)

                                    }

                                  

                                    func startAlien(interval: Double) {

                                        alienTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(moveAlien), userInfo: nil, repeats: true)

                                        alienX = randomStartAlien()

                                        BattleField.aliens.insert(self)    //wstawienie do kolekcji

                                    }

                                  

                                    func stopAlien() {

                                        alienTimer.invalidate()

                                        BattleField.aliens.remove(self)

                                        self.removeFromSuperview()

                                    }

                                  

                                    @objc func moveAlien() {

                                        if alienX > 10 && alienX < BattleViewController.dimXY - 10 {

                                            let leftOrRight = Bool.random()

                                            if leftOrRight {

                                                alienX += CGFloat(alienStep())

                                            } else {

                                                alienX -= CGFloat(alienStep())

                                            }

                                        } else {

                                            if alienX <= 10 {

                                                alienX += CGFloat(alienStep())

                                            }

                                            if alienX >= BattleViewController.dimXY - 10 {

                                                alienX -= CGFloat(alienStep())

                                            }

                                        }

                                        alienCounter += alienStep()

                                        collisionCheck()

                                        alienY = CGFloat(alienCounter)

                                        if alienY >= BattleViewController.dimXY {

                                            stopAlien()

                                        }

                                        self.setNeedsDisplay()

                                    }

                                  

                                    func randomStartAlien() -> CGFloat {

                                        let startAlienPosition = Int.random(in: 1...Int(BattleViewController.dimXY) / 10 - 1)

                                        return CGFloat(startAlienPosition * 10)

                                    }

                                  

                                    func getAlienX() -> CGFloat {

                                        return alienX

                                    }

                                  

                                    func getAlienY() -> CGFloat {

                                        return alienY

                                    }

                                  

                                    func alienStep() -> Int {

                                        return 2

                                    }

                                  

                                    func makesGameOver() -> Bool {

                                        return true

                                    }

                                  

                                    func collisionCheck() {

                                        let dist = Ship.setShipRange() + Alien.setAlienRange()

                                        for oneAlien in BattleField.aliens {

                                            if oneAlien.getAlienY() >= BattleViewController.dimXY - 30 / screenSettings.minimalScaleFactor() {

                                                if oneAlien.getAlienX() - BattleViewController.shipX <= dist && BattleViewController.shipX - oneAlien.getAlienX() <= dist {

                                                    if oneAlien.makesGameOver() {

                                                        BattleViewController.alienStopEngine()

                                                        BattleViewController.bonusStopEngine()

                                                        Difficulty.stopDifficultyTimer()

                                                        for anyAlien in BattleField.aliens {

                                                            anyAlien.stopAlien()

                                                        }

                                                    } else {

                                                        BattleViewController.score += 50

                                                        oneAlien.stopAlien()

                                                    }

                                                    BattleViewController.scoreLabel.text = "Score: " + String(BattleViewController.score)

                                                }

                                            }

                                        }

                                    }

                                  

                                }

                                • Re: make static function that brings UILabel
                                  chuba Level 1 Level 1 (0 points)

                                  class Missile: UIView {

                                    

                                      let screenSettings = ScreenSettings()

                                      let missileStep = 4

                                      let missileInterval: Double = 0.02

                                    

                                      var missileTimer = Timer()

                                      var missileCounter: Int = 17

                                      var missileX: CGFloat!

                                      var missileY: CGFloat = BattleViewController.dimXY

                                    

                                      override init(frame: CGRect) {

                                          super.init(frame: frame)

                                          self.backgroundColor = UIColor.clear

                                      }

                                    

                                      required init?(coder aDecoder: NSCoder) {

                                          fatalError("init(coder:) has not been implemented")

                                      }

                                    

                                      func setMissile(x: CGFloat, y: CGFloat) {

                                          let scale = screenSettings.minimalScaleFactor()

                                          let missile = UIBezierPath()

                                          missile.move(to: CGPoint(x: (x - 5) * scale, y: (y + 5) * scale))

                                          missile.addLine(to: CGPoint(x: (x - 5) * scale, y: y * scale))

                                          missile.move(to: CGPoint(x: (x + 5) * scale, y: (y + 5) * scale))

                                          missile.addLine(to: CGPoint(x: (x + 5) * scale, y: y * scale))

                                          let missileLeft = UIBezierPath(arcCenter: CGPoint(x: (x - 5) * scale, y: (y + 8) * scale), radius: 2 * scale, startAngle: 0, endAngle: .pi, clockwise: false)

                                          let missileRight = UIBezierPath(arcCenter: CGPoint(x: (x + 5) * scale, y: (y + 8) * scale), radius: 2 * scale, startAngle: 0, endAngle: .pi, clockwise: false)

                                   

                                          UIColor.red.setFill()

                                          UIColor.yellow.setStroke()

                                   

                                          missile.lineWidth = BattleViewController.lineWidth * scale / 2

                                          missileLeft.lineWidth = BattleViewController.lineWidth * scale / 2

                                          missileRight.lineWidth = BattleViewController.lineWidth * scale / 2

                                        

                                          missileLeft.fill()

                                          missileRight.fill()

                                          missile.stroke()

                                          missileLeft.stroke()

                                          missileRight.stroke()

                                      }

                                    

                                      override func draw(_ rect: CGRect) {

                                          setMissile(x: missileX, y: missileY)

                                      }

                                    

                                      func startMissile() {

                                          missileTimer = Timer.scheduledTimer(timeInterval: missileInterval, target: self, selector: #selector(moveMissile), userInfo: nil, repeats: true)

                                          missileX = BattleViewController.shipX

                                          BattleField.missiles.insert(self)    //wstawienie do kolekcji

                                      }

                                    

                                      func stopMissile() {

                                          missileTimer.invalidate()

                                          BattleField.missiles.remove(self)

                                          self.removeFromSuperview()

                                      }

                                    

                                      @objc func moveMissile() {

                                          missileCounter += missileStep

                                          hitCheck()

                                          missileY = BattleViewController.dimXY - CGFloat(missileCounter)

                                          if missileCounter > Int(BattleViewController.dimXY - BattleViewController.shipY) {

                                              stopMissile()

                                          }

                                          self.setNeedsDisplay()

                                      }

                                    

                                      func getMissileX() -> CGFloat {

                                          return missileX

                                      }

                                    

                                      func getMissileY() -> CGFloat {

                                          return missileY

                                      }

                                    

                                      func hitCheck() {

                                          for oneMissile in BattleField.missiles {

                                              for oneAlien in BattleField.aliens {

                                                  if oneAlien.getAlienX() - oneMissile.getMissileX() <= 14 && oneAlien.getAlienX() - oneMissile.getMissileX() >= -14 && oneAlien.getAlienY() - oneMissile.getMissileY() <= 5 && oneAlien.getAlienY() - oneMissile.getMissileY() >= -5 {

                                                      if oneAlien.makesGameOver() {

                                                          BattleViewController.score += 10

                                                          BattleViewController.scoreLabel.text = "Score: " + String(BattleViewController.score)

                                                          Explosion.explosionX = oneAlien.getAlienX()

                                                          Explosion.explosionY = oneAlien.getAlienY()

                                                      }

                                                      oneMissile.stopMissile()

                                                      oneAlien.stopAlien()

                                                      BattleViewController.explodeNow()

                                                  }

                                              }

                                          }

                                      }

                                    

                                  }

                                  • Re: make static function that brings UILabel
                                    chuba Level 1 Level 1 (0 points)

                                    I am sorry, now I must be off for about three hours... so I will analise everything this evening later. Thank You very much, see You later

                                      • Re: make static function that brings UILabel
                                        Claude31 Level 8 Level 8 (6,365 points)

                                        OK, tell when you return.

                                         

                                        One precision for what you have to write in BattleFieldController:

                                         

                                        Once you created a missile

                                        let myMissile = Missile()

                                         

                                        add the following

                                        myMissile.parentVC = self (which is BattleField) 

                                         

                                        You will do the same for any missile or alien you create.

                                          • Re: make static function that brings UILabel
                                            chuba Level 1 Level 1 (0 points)

                                            any idea?

                                              • Re: make static function that brings UILabel
                                                chuba Level 1 Level 1 (0 points)

                                                unfortunately, I set in Alien.class:

                                                var parentVC: UIViewController?

                                                 

                                                I set:

                                                    @objc func alienEngine() {

                                                        if nextAlien {

                                                            let alien = Alien()

                                                            alien.parentVC = self

                                                            setBattleField(object: alien)

                                                            alien.startAlien(interval: alienInterval)

                                                        }

                                                        nextAlien = Bool.random()

                                                    }

                                                  (that is a metod making Alien instances and it exists in BattleViewController)

                                                 

                                                and then I have a method in Alien class named collisionCheck(), in that method I need to call setGameOverInfo() which is placed in BattleViewController... but I can't. It is impossible to write parentVC.setGameOverInfo... Really do not what to do...

                                                greetings, maybe You will be able to help thanks...

                                                  • Re: make static function that brings UILabel
                                                    Claude31 Level 8 Level 8 (6,365 points)

                                                    It is hard to understand what you are doing.

                                                     

                                                    Could you post the complete ALien or Missile class (please use code formatter <> to make it readable).

                                                     

                                                    And then, post the code of BattleField where you create aliens or Missiles.

                                                    Is it the alienEngine() ?

                                                    If so, how is it called ?

                                                • Re: make static function that brings UILabel
                                                  chuba Level 1 Level 1 (0 points)

                                                  Hallo, could You help me? Do you have any idea?

                                                    • Re: make static function that brings UILabel
                                                      chuba Level 1 Level 1 (0 points)

                                                      Here You are, I have cut less important code responsible for pure graphic maiking object. Below my missile class with hitCheck method. After that main class of BattleViewController

                                                       

                                                      class Alien: UIView {
                                                         
                                                          let screenSettings = ScreenSettings()
                                                         
                                                          var alienTimer = Timer()
                                                          var alienCounter: Int = 0
                                                          var alienX: CGFloat!
                                                          var alienY: CGFloat = 0
                                                          var leftOrRight = Bool.random()
                                                          var alienChangeView = 1
                                                      
                                                          override init(frame: CGRect) {
                                                              super.init(frame: frame)
                                                              self.backgroundColor = UIColor.clear
                                                          }
                                                         
                                                          required init?(coder aDecoder: NSCoder) {
                                                              fatalError("init(coder:) has not been implemented")
                                                          }
                                                         
                                                          func setAlienRange() -> CGFloat {
                                                              return 8
                                                          }
                                                         
                                                          func setAlien(x: CGFloat, y: CGFloat) {
                                                              let scale = screenSettings.minimalScaleFactor()
                                                              let alienArc = UIBezierPath(arcCenter: CGPoint(x: x * scale, y: y * scale), radius: setAlienRange() * scale, startAngle: 0.06 * .pi, endAngle: 0.94 * .pi, clockwise: true)
                                                              alienArc.stroke()
                                                          }
                                                         
                                                          override func draw(_ rect: CGRect) {
                                                              setAlien(x: alienX, y: alienY)
                                                          }
                                                         
                                                          func startAlien(interval: Double) {
                                                              alienTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(moveAlien), userInfo: nil, repeats: true)
                                                              alienX = randomStartAlien()
                                                              BattleField.alienCollection.insert(self)    //wstawienie do kolekcji
                                                          }
                                                         
                                                          func stopAlien() {
                                                              alienTimer.invalidate()
                                                              BattleField.alienCollection.remove(self)
                                                              self.removeFromSuperview()
                                                          }
                                                         
                                                          @objc func moveAlien() {
                                                              if alienX > 10 && alienX < BattleViewController.dimXY - 10 {
                                                                  if Int(alienY) % 5 == 0 {
                                                                      leftOrRight = Bool.random()
                                                                  }
                                                                  if leftOrRight {
                                                                      alienX += CGFloat(alienStep())
                                                                  } else {
                                                                      alienX -= CGFloat(alienStep())
                                                                  }
                                                              } else {
                                                                  if alienX <= 10 {
                                                                      alienX += CGFloat(alienStep())
                                                                  }
                                                                  if alienX >= BattleViewController.dimXY - 10 {
                                                                      alienX -= CGFloat(alienStep())
                                                                  }
                                                              }
                                                              alienCounter += alienStep()
                                                              alienChangeView *= -1
                                                              collisionCheck()
                                                              alienY = CGFloat(alienCounter)
                                                              if alienY >= BattleViewController.dimXY {
                                                                  stopAlien()
                                                              }
                                                              self.setNeedsDisplay()
                                                          }
                                                         
                                                          func randomStartAlien() -> CGFloat {
                                                              let startAlienPosition = Int.random(in: 1...Int(BattleViewController.dimXY) / 10 - 1)
                                                              return CGFloat(startAlienPosition * 10)
                                                          }
                                                         
                                                          func getAlienX() -> CGFloat {
                                                              return alienX
                                                          }
                                                         
                                                          func getAlienY() -> CGFloat {
                                                              return alienY
                                                          }
                                                         
                                                          func alienStep() -> Int {
                                                              return 1
                                                          }
                                                         
                                                          func makesGameOver() -> Bool {
                                                              return true
                                                          }
                                                         
                                                          func collisionCheck() { //poprawić odległości zwłaszcza przy mniejszym bonusie, rozróżnić
                                                              let dist = Ship.setShipRange() + setAlienRange()
                                                              for oneAlien in BattleField.alienCollection {
                                                                  if oneAlien.getAlienY() >= BattleViewController.dimXY - 30 / screenSettings.minimalScaleFactor() {
                                                                      if oneAlien.getAlienX() - BattleViewController.shipX <= dist && BattleViewController.shipX - oneAlien.getAlienX() <= dist {
                                                                          if oneAlien.makesGameOver() {
                                                                              BattleViewController.alienStopEngine()
                                                                              BattleViewController.bonusStopEngine()
                                                                              Difficulty.stopDifficultyTimer()
                                                                              for anyAlien in BattleField.alienCollection {
                                                                                  anyAlien.stopAlien()
                                                                              }
                                                                          } else {
                                                                              BattleViewController.score += 50
                                                                              oneAlien.stopAlien()
                                                                          }
                                                                          BattleViewController.scoreLabel.text = "Score: " + String(BattleViewController.score)
                                                                      }
                                                                  }
                                                              }
                                                          }
                                                         
                                                      }

                                                      And below is BattleViewController. I want to call setGameOverInfo() just from inside of collisionCheck(), about line 102. Thank You.

                                                       

                                                      struct BattleField {
                                                          static var alienCollection = Set()
                                                          static var missileCollection = Set()
                                                      }
                                                      
                                                      class BattleViewController: UIViewController {
                                                         
                                                          let screenSettings = ScreenSettings()
                                                          let ship = Ship()
                                                          let alienInterval: Double = 0.1
                                                          let bonusInterval: Double = 0.12
                                                         
                                                          var shipXDeltaTouch: CGFloat = 0
                                                          var nextAlien = true
                                                          var nextBonus = false
                                                         
                                                          static let dimXY: CGFloat = 260
                                                          static let shipY: CGFloat = 5
                                                          static let scoreLabel = UILabel()
                                                          static let lineWidth: CGFloat = 2
                                                         
                                                          static var shipX: CGFloat!
                                                          static var alienEngineTimer = Timer()
                                                          static var score: Int = 0
                                                         
                                                          override func viewDidLoad() {
                                                              super.viewDidLoad()
                                                             
                                                              let shipFirstPosition = BattleViewController.dimXY / 2
                                                              BattleViewController.shipX = shipFirstPosition
                                                             
                                                              BattleViewController.scoreLabel.text = "Score: " + BattleViewController.updatedScore()
                                                             
                                                              setScoreLabel()
                                                              setBattleField(object: ship)
                                                              alienStartEngine()
                                                              difficulty.startDifficultyTimer()
                                                             
                                                              // Do any additional setup after loading the view, typically from a nib.
                                                          }
                                                         
                                                         
                                                          func setScoreLabel() {
                                                          }
                                                         
                                                          func setBattleField(object: UIView) {
                                                              let scale = screenSettings.minimalScaleFactor()
                                                              let battleFieldRect: CGFloat = BattleViewController.dimXY * scale
                                                             
                                                              view.addSubview(object)
                                                              object.translatesAutoresizingMaskIntoConstraints = false
                                                             
                                                              let bFCenterXConstraint = NSLayoutConstraint(item: object, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
                                                              let bFCenterYConstraint = NSLayoutConstraint(item: object, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: -20 * scale)
                                                              let bFWidthConstraint = NSLayoutConstraint(item: object, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: battleFieldRect)
                                                              let bFHeightConstraint = NSLayoutConstraint(item: object, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: battleFieldRect)
                                                             
                                                              view.addConstraints([bFCenterXConstraint, bFCenterYConstraint, bFWidthConstraint, bFHeightConstraint])
                                                          }
                                                               
                                                          func alienStartEngine() {
                                                              BattleViewController.alienEngineTimer = Timer.scheduledTimer(timeInterval: 1.2, target: self, selector: #selector(alienEngine), userInfo: nil, repeats: true)
                                                          }
                                                         
                                                          static func alienStopEngine() {
                                                              alienEngineTimer.invalidate()
                                                          }
                                                         
                                                          @objc func alienEngine() {
                                                              if nextAlien {
                                                                  let alien = Alien()
                                                                  setBattleField(object: alien)
                                                                  alien.startAlien(interval: alienInterval / difficulty.difficultyStage)
                                                              }
                                                              nextAlien = Bool.random()
                                                          }
                                                            
                                                          func setGameOverInfo() {
                                                              let gameOver = UILabel()
                                                              let scale = screenSettings.minimalScaleFactor()
                                                              gameOver.text = "Game over\n" + "Your score: " + BattleViewController.updatedScore()
                                                              gameOver.numberOfLines = 2
                                                              gameOver.font = UIFont.systemFont(ofSize: 24 * scale)
                                                              gameOver.textColor = UIColor.white
                                                              gameOver.textAlignment = .center
                                                             
                                                              view.addSubview(gameOver)
                                                              gameOver.translatesAutoresizingMaskIntoConstraints = false
                                                             
                                                              let centerXGOConstraint = NSLayoutConstraint(item: gameOver, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
                                                              let centerYGOConstraint = NSLayoutConstraint(item: gameOver, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relati
                                                        • Re: make static function that brings UILabel
                                                          Claude31 Level 8 Level 8 (6,365 points)

                                                          setGameOverInfo is not a static method in your code ; hence you cannot call with BattleFieldController.setGameOverInfo()

                                                           

                                                          So, my advice is to:

                                                           

                                                          - indide Alien class,

                                                           

                                                          add at line 11

                                                          var parentVC : BattleViewController?

                                                           

                                                          At line 102 or so, call

                                                          parentVC?.setGameOverInfo()

                                                           

                                                          - inside BattleViewController, when you create an alien (I understand it is line 71 only, am I correct ?

                                                          If so, at line 72, add

                                                          alien.parentVC = self // Which is the BattleViewController in which you added the alien view.