swiftxcodebuttonsprite-kitskspritenode

Trying to create method to access the buttons when pressed on swift?


import UIKit
import SpriteKit
import GameplayKit

struct Question {   
    var Question : String!
    var Answers : [String]!
    var AnswerNumber : Int!
}

class LevelOne: SKScene {
    
    var button = Button()
    
    var buttons = [Button]()
    let Question_met = UILabel(frame: CGRect(x: 0.3, y: 0.3, width: 40, height: 21))
    
    var Questions = [Question]()
       
    var QNumber = Int()
    
    var buttonNames = [""]
    
    override func didMove(to view: SKView) {
        
        let background = SKSpriteNode(imageNamed: "background")
        background.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
        background.zPosition = 0
        self.addChild(background)
        
        QuestionFunction()
        
        ButtonFuction()
         
        PickQuestion()
        
    }
    
    @objc func QuestionFunction(){
        
        Questions = [Question(Question: "What is a Car ?", Answers: ["Bat","Cat","Vehicle","Pat"], AnswerNumber: 3),
        
        Question(Question: "What is a plane ?", Answers: ["Bat","Aircraft","Cat","Pat"], AnswerNumber: 2),
        
        Question(Question: "What is a ant ?", Answers: ["Bat","Cat","Vegetable","Insect"], AnswerNumber: 4),
        
        Question(Question: "What is a Apple ?", Answers: ["Bat","Cat","Fruit","Pat"], AnswerNumber: 3),]
        
        Question_met.frame = CGRect(x: 330, y: 70, width: 200, height: 21)
        Question_met.backgroundColor = UIColor.orange
        Question_met.textColor = UIColor.white
        Question_met.textAlignment = NSTextAlignment.center
        Question_met.text = "What caused Global Warming ?"
        self.view?.addSubview(Question_met)
        
    }
    
    @objc func ButtonFuction(){
        
        let stacView = UIStackView()
        stacView.spacing = 12
        stacView.distribution = .fillEqually
        stacView.axis = .horizontal
        stacView.translatesAutoresizingMaskIntoConstraints = false
        view!.addSubview(stacView)
        
        buttonNames = ["One","Two","Three","Four"]
        
        for name in buttonNames {
            button = Button()
            button.setTitle(name, for: .normal)
            stacView.addArrangedSubview(button)
            buttons.append(button)
        }
    
        NSLayoutConstraint.activate([stacView.centerXAnchor.constraint(equalTo: view!.centerXAnchor),stacView.centerYAnchor.constraint(equalTo: view!.centerYAnchor),stacView.widthAnchor.constraint(equalToConstant: 350),stacView.heightAnchor.constraint(equalToConstant:70)])
        
    }
    
    @objc func PickQuestion(){
        
        if Questions.count > 0{
            QNumber = 0
            Question_met.text = Questions[QNumber].Question
            
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions[QNumber].Answers[i], for: .normal)
            }
            Questions.remove(at: QNumber)
        }
        else {
            print("Done!")
        }
    }
    
    @objc func handleButton() {
        
        print("")
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    

    }
}

I created a quiz based game and programmed my button manually but not sure how to create methods that would handle when the button is pressed.


Solution

  • Not sure entirely what you are asking for so going to state what I think you are asking.

    You are simply asking on how to connect a button to action.

    You're button is declared button = UIButton() in the loop then the action would be handleButton method declared below.

    You can simply do addTarget(:) for the button.

    button.addTarget(self, action:#selector(handleButton), for: .touchUpInside)
    

    You can google Swift Classname, i.e. Swift UIButton to determine the methods for that class. For example inside UIButton, we can see there is a method identified as addTarget(_:action:for).

    From Apple's Docs:

    You connect a button to your action method using the addTarget(_:action:for:) method or by creating a connection in Interface Builder. The signature of an action method takes one of three forms, which are listed in Listing 1. Choose the form that provides the information that you need to respond to the button tap.

    Edit: OP decided to ask how to assign button functionality within a loop. To do this, you need a list of functions aka Selectors that you can reference.

    let selectors:[Selector] = [#selector(handleButton1), #selector(handleButton2, #selector(handleButton3)]
    
    for i in 0..<3 {
        button.addTarget(self, action: selectors[i], for: .touchUpInside)
    }