Search code examples
iosswiftbuttontouchibaction

IBAction sometimes not being called when touching buttons - Swift


I am trying to develop a word game where players click buttons to select letters.

There seems to be problem where my buttons sometimes do not register touches. It only seems to occur if there is a pause for a few seconds with no user interaction before a button touch. If the first touch works, quick follow up touches also work.

@IBAction func tileButton1(_ sender: UIButton) {
    print("Tile 1 Selected")
    tileSelected(tileSelected: 1)
}

@IBAction func clearButton(_ sender: Any) {
    clearSelectedTiles()
}


@IBAction func SubmitButton(_ sender: Any) {
    //print("Submit Button Pressed")
    checkIfSubmittedWordIsValid()
}

checkIfSubmittedWordIsValid

func checkIfSubmittedWordIsValid() {
    var alreadySelectedWords: [String] = []
    switch currentPlayer {
    case 1:
        alreadySelectedWords = player1words
    case 2:
        alreadySelectedWords = player2words
    case 3:
        alreadySelectedWords = player3words
    case 4:
        alreadySelectedWords = player4words
    default:
        break
    }
    if currentWord.characters.count < 3 {
        print("Too short")
        playSound(fileName: "invalidWord", fileExtension: "aiff", volume: 1.0)
    } else if alreadySelectedWords.contains(currentWord) {
        print("Already picked this word")
        playSound(fileName: "invalidWord", fileExtension: "aiff", volume: 1.0)
    } else if wordList.contains(currentWord.lowercased()) {
        print("Valid Word")
        playSound(fileName: "goodWord", fileExtension: "wav", volume: 0.5)
        addWordToPlayerList(word: currentWord)
    } else {
        print("Not in dictionary")
        playSound(fileName: "invalidWord", fileExtension: "aiff", volume: 1.0)
    }
    clearSelectedTiles()
}

clearSelectedTiles

func clearSelectedTiles() {
    tile1.alpha = 1
    tile2.alpha = 1
    tile3.alpha = 1
    tile4.alpha = 1
    tile5.alpha = 1
    tile6.alpha = 1
    tile7.alpha = 1
    tile8.alpha = 1
    tile9.alpha = 1
    tile10.alpha = 1
    tile11.alpha = 1
    tile12.alpha = 1
    tile13.alpha = 1
    tile14.alpha = 1
    tile15.alpha = 1
    tile16.alpha = 1
    selectedTiles.removeAll()
    validTiles = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
    selectedWordLabel.text = ""
    currentWord = ""
}

Nothing gets printed when the issue occurs. Following up quickly with a second touch will trigger the IBAction and print to log.

It seems to happen also with all my other buttons (another 15 'tile' buttons and a 'Clear' and 'Submit' button)

What am I doing wrong?

Link to video showing issue First few touches work but then weirdness.

Storyboard

Touch Down event

tileSelected

func tileSelected(tileSelected: Int) {
    if isTileValid(tile: tileSelected) {
        selectedTiles.append(tileSelected)
        var surroundingTiles: [Int] = []
        switch tileSelected {
        case 1:
            tile1.alpha = 0.5
            surroundingTiles = [2,5,6]
        case 2:
            tile2.alpha = 0.5
            surroundingTiles = [1,3,5,6,7]
        case 3:
            tile3.alpha = 0.5
            surroundingTiles = [2,4,6,7,8]
        case 4:
            tile4.alpha = 0.5
            surroundingTiles = [3,7,8]
        case 5:
            tile5.alpha = 0.5
            surroundingTiles = [1,2,6,9,10]
        case 6:
            tile6.alpha = 0.5
            surroundingTiles = [1,2,3,5,7,9,10,11]
        case 7:
            tile7.alpha = 0.5
            surroundingTiles = [2,3,4,6,8,10,11,12]
        case 8:
            tile8.alpha = 0.5
            surroundingTiles = [3,4,7,11,12]
        case 9:
            tile9.alpha = 0.5
            surroundingTiles = [5,6,10,13,14]
        case 10:
            tile10.alpha = 0.5
            surroundingTiles = [5,6,7,9,11,13,14,15]
        case 11:
            tile11.alpha = 0.5
            surroundingTiles = [6,7,8,10,12,14,15,16]
        case 12:
            tile12.alpha = 0.5
            surroundingTiles = [7,8,11,15,16]
        case 13:
            tile13.alpha = 0.5
            surroundingTiles = [9,10,14]
        case 14:
            tile14.alpha = 0.5
            surroundingTiles = [9,10,11,13,15]
        case 15:
            tile15.alpha = 0.5
            surroundingTiles = [10,11,12,14,16]
        case 16:
            tile16.alpha = 0.5
            surroundingTiles = [11,12,15]
        default:
            // do nothing
            break
        }
        updateValidTiles(surroundingTiles: surroundingTiles)
        //print("Updated Valid Tiles")
        //print(validTiles)
        //print("Selected Tiles")
        //print(selectedTiles)
        currentWord = currentWord + boardTiles[tileSelected - 1].tileLetter
        selectedWordLabel.text = currentWord
    }
}

Solution

  • I had some labels constrained to the Top Layout Guide.bottom even though I was hiding the status bar with override var prefersStatusBarHidden.

    Changing the relevant label constraints to topMargin instead of Top Layout Guide.bottom has solved my problem with touches sometimes being missed.