Search code examples
swiftdatabasesqliteuibuttonplist

Swift 3 - UIButton adding setTitle from plist and database


I have plist file and database, in the plist file has English letters and in database row has String for example (London) and I convert String to characters array and appended into plist file. I created 14 UIButtons by (for loop) and I was given setTitle from row of database and given shuffle and adding letters from plist and given shuffle.

So my problem is when adding my characters from database is show me just characters from database and shuffled like this:

enter image description here

But I don’t need just that I need first adding to setTitle all characters from database and shuffled and the remaining empty button adds from the plist file like this :

enter image description here

How can I do like above picture (2nd picture) ?!

This my code, What's wrong with writing the code ?? :

let fileName : String = " EnglishLetters"
let fileExt : String = "plist"
let pathRes = Bundle.main.path(forResource: fileName, ofType: fileExt)
let pathDict = NSDictionary(contentsOfFile: pathRes!)
var letters : [String] = pathDict?.object(forKey: "Letters") as! [String]

for data in listdata { // SQLite database

    let dataAnswer = data.ans // ans is a row in the SQLite database 
    let dataArrayAnswer = dataAnswer.characters.map{String($0)}
    letters.append(contentsOf: dataArrayAnswer)

    for char in dataArrayAnswer {}

        for i in 1...14 {

            let tileButton = UIButton(type: .roundedRect)
            let lettersAns = dataArrayAnswer.shuffled()[letters.distance(from: id, to: id)] // id is parameter
            tileButton.setTitle(lettersAns, for: .normal)
            tileButton.titleLabel?.font = UIFont(name: "HelveticaNeueW23forSKY-Bd", size: 15)
            tileButton.setTitleColor(.black, for: .normal)
            tileButton.setBackgroundImage(UIImage(named: "Cell"), for: .normal)            
            tileButton.addTarget(self, action: #selector(moveTile(sender:)), for: .touchUpInside)
            xAxis = xAxis + buttonWidth + space

            view.addSubview(tileButton)


            if i%7 == 0 {

               xAxis = emptySpace / 2
               yAxis = yAxis2 + space

            }

        }
    }
 }

Solution

  • What you need to do is first create an array with all your target letters (shuffled and added random letters) and then run over that array to update the button titles.

    Start by filling a 14 value array with random letters:

    var presentedLetters : [String] = [String]()
    var availableLetters : [String] = pathDict?.object(forKey: "Letters") as! [String]
    
    var availableLetterIndexes : [Int] = Array(0..<availableLetters.count)
    
    for letterAt in 0 ..< 14
    {
        let randomIndex : Int = Int(arc4random_uniform(UInt32(availableLetterIndexes.count)))
        var charIndex : Int = availableLetterIndexes[randomIndex]
    
        presentedLetters.append(availableLetters[charIndex])
    
        availableLetterIndexes.remove(at: randomIndex)
    }
    

    Generate available positions for the answer string:

    var availableIndexes : [Int] = Array(0..<presentedLetters.count)
    

    Then go over your letters from the db and add them in random places inside the target array (while remembering added indexes to prevent overriding letters):

    var addedAnswerIndexes : [Int] = [Int]()
    
    let answerString = data.ans // ans is a row in the SQLite database 
    let answerCharacters = answerString.characters.map{String($0)}
    
    for answerCharAt in answerCharacters
    {
        let randomIndex : Int = Int(arc4random_uniform(UInt32(availableIndexes.count)))
        var charIndex : Int = availableIndexes[randomIndex]
    
        presentedLetters[charIndex] = answerCharAt
    
        availableIndexes.remove(at: randomIndex)
    }
    

    And then presentedLetters will have an array of all relevant values.

    EDIT:

    To add the titles to the buttons, just go over presentedLetters array:

            for i in 1...14 {
    
                let tileButton = UIButton(type: .roundedRect)
                tileButton.setTitle(presentedLetters[i-1], for: .normal)
    
                ......
    
            }
        }
    

    Good luck!