zzzzou
zzzzou

Reputation: 197

IBAction Buttons have same functionality. Is it possible to refactor?

I'm learning Swift and I'm making a tic-tac-toe game now. Here is the image of the game and everything works fine so far.image of tic-tac-toe. However, I was wondering if there is a way to refactor the code or not.

I added a plate image to each button (so you can see 3 X 3 buttons), so when a user taps the button, the plate image becomes either an apple image or a pineapple image. In the code below, I made IBAction for each button (i.e. func plate1Pressed()), but every IBAction execute the same function, which is changePlateImage(plate: sender). So far, I only have 9 buttons in total, so I can just make IBAction 9 times and put changePlateImage(plate: sender) in them, however, I was thinking if I had to make more square games like Reversi, I had to make 8 X 8 IBActions, which is kind of terrifying...

So is there any way to refactor my code? instead of adding IBActions 9 times and put the same function in them?

import UIKit

class GameScreenViewController: UIViewController {

var isPlayer1 = true

override func viewDidLoad() {
    super.viewDidLoad()
}



// when player 1 taped a button, change isPlayer1 to flase


func displayHandPointer () {
    // some codes here...
}


func chnagePlayerTurn () {
    // some codes here...
}




func changePlateImage (plate: UIButton) {

    let fruitImage = isPlayer1 ? K.Image.apple : K.Image.pineapple

    plate.setImage(UIImage(named: fruitImage), for: .normal)

    chnagePlayerTurn()
    displayHandPointer()
}





//MARK: - IBA actions for board game

@IBAction func plate1Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}


@IBAction func plate2Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}


@IBAction func plate3Pressed(_ sender: UIButton) {
    
    changePlateImage(plate: sender)
}


@IBAction func plate4Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}


@IBAction func plate5Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}


@IBAction func plate6Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}


@IBAction func plate7Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}


@IBAction func plate8Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}

@IBAction func plate9Pressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}

// and codes go on...

}

Upvotes: 0

Views: 77

Answers (2)

ZG324
ZG324

Reputation: 66

You don't need to create 9 IBAction to do that. sender is passed in as a parameter when it's tapped, and it differs each time when different plate is tapped.

So only one IBAction is needed to call changePlateImage.

Do the following:

Connect plate1 to plate9 to platesPressed IBAction func
@IBAction func platesPressed(_ sender: UIButton) {
    changePlateImage(plate: sender)
}

func changePlateImage (plate: UIButton) {
    // keep the same code
}

Upvotes: 0

David Mempin
David Mempin

Reputation: 55

You can use the same IBAction for all UIButtons and then use tags to know which buttons you are pressing.

@IBAction func platePressed(_ sender: Any) {
    let button = sender as! UIButton
    if button.tag == 1 {
        // do something
    }
}

View tags can be set inside the interface builder enter image description here

Upvotes: 0

Related Questions