NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

Trying to create a reveal word for hangman game using replaceSubrange(range: with) method

Forums > 100 Days of Swift

in this line

... currentAnswer.text?.replaceSubrange(currentIndex...currentIndex, with: characterString) ...

and this line

... currentAnswer.text = currentAnswer.text?.replaceSubrange(range, with: characterString) ...

are giving me the errors "Type of expression is ambiguous without more context" and "No exact matches in call to instance method 'replaceSubrange", respectively.

I am trying to do two things. after extracting the buttontitle, i turned it into both a string and character. i am trying to check currentWord to see if it contains the buttonTitle variable, and if it does, I want to reveal the letter in the currentAnswer textfield. I got it to work, but the order was wrong, the position of each letter revealed was random. The second issue was if a letter appears in the word the user is trying to guess more than once, that letter should appear as many times in the currentAnswer textfield but it wouldn't and I have disable each letter if it is tapped so I obviously can't retap the letter again. Thanks for your help!

import UIKit

class ViewController: UIViewController {
            var currentIndex = 0
            var currentWord = String()
            var scoreLabel: UILabel!
            var wordLabel: UILabel!
            var letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
            var currentAnswer: UILabel!
            var usedLetters = [Character]()
            var wordList = ["arsenal", "mancity", "chelsea", "acmilan", "atlmdrd", "rmadrid", "munited"]
            var activatedButtons = [UIButton]()
            var letterButtonsArray = [UIButton]()
            var score = 0

    override func loadView() {

        view = UIView()
        view.backgroundColor = .white

        scoreLabel = UILabel()
        scoreLabel.translatesAutoresizingMaskIntoConstraints = false
        scoreLabel.text = "SCORE: "
        scoreLabel.font = UIFont.systemFont(ofSize: 25)

        wordLabel = UILabel()
        wordLabel.translatesAutoresizingMaskIntoConstraints = false
        wordLabel.numberOfLines = 0
        wordLabel.font = UIFont.systemFont(ofSize: 28)
        wordLabel.text = "Teams"
        wordLabel.textAlignment = .center
        wordLabel.setContentHuggingPriority(UILayoutPriority(1), for: .vertical)

        currentAnswer = UILabel()
        currentAnswer.textAlignment = .left
        currentAnswer.translatesAutoresizingMaskIntoConstraints = false
        currentAnswer.text = "_______"
        currentAnswer.font = UIFont.systemFont(ofSize: 36)
        currentAnswer.isUserInteractionEnabled = false

        let submit = UIButton(type: .system)
        submit.translatesAutoresizingMaskIntoConstraints = false
        submit.setTitle("SUBMIT", for: .normal)
        submit.addTarget(self, action: #selector(submitTapped), for: .touchUpInside)

        let buttonView = UIView()
        buttonView.translatesAutoresizingMaskIntoConstraints = false


            scoreLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
            scoreLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),

            wordLabel.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor, constant: 25),
            wordLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
            wordLabel.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor, constant: 55),

            currentAnswer.topAnchor.constraint(equalTo: wordLabel.bottomAnchor, constant: 20),
            currentAnswer.widthAnchor.constraint(equalTo: view.layoutMarginsGuide.widthAnchor, constant: 0.5),
            currentAnswer.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 320),
            submit.topAnchor.constraint(equalTo: currentAnswer.bottomAnchor, constant: 20),
            submit.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            buttonView.topAnchor.constraint(equalTo: submit.bottomAnchor, constant: 20),
            buttonView.widthAnchor.constraint(equalToConstant: 550),
            buttonView.heightAnchor.constraint(equalToConstant: 320),
            buttonView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor, constant: -20),
            buttonView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            buttonView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor, constant: 0),
            buttonView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor, constant: 0)


        let width = 80
        let height = 60

        for row in 0..<3{
            for col in 0..<9{
                let letterButton = UIButton(type: .system)
                letterButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
                letterButton.setTitle("A", for: .normal)
                let frame = CGRect(x: col*width, y: row*height, width: width, height: height)
                letterButton.frame = frame
                letterButton.addTarget(self, action: #selector(letterTapped), for: .touchUpInside)


        let lastbutton = buttonView.subviews.last


    override func viewDidLoad() {


        //end of view did load

    func loadLevel(){
        if letters.count == letterButtonsArray.count{
            for i in 0..<letterButtonsArray.count{
                letterButtonsArray[i].setTitle(letters[i], for: .normal)

    func startGame(){
        currentAnswer.text = ""

    @objc func letterTapped(_ sender: UIButton){

//        let characterlist ={Array($0)}
//        for sublist in characterlist {
//            for char in sublist{
//                usedLetters.append(char)
//                print("usedLetters are \(usedLetters)")
        guard let buttonTitle = sender.titleLabel?.text else {return}

        let char = Character(buttonTitle.lowercased())
        let characterString = String(char)
        print("used letters is \(usedLetters)")
        sender.isHidden = true
        currentWord = wordList[currentIndex]
//        for character in currentWord{
//            var CHARACTER = String()
//            if usedLetters.contains(character){
//                 CHARACTER = String(character)
//            }
//            currentAnswer.text? += CHARACTER
//        }

        if currentWord.contains(characterString){

            var indices = [Int]()

            for (index, letter) in currentWord.enumerated() {
                if letter == char{

            for index in indices {
                let currentIndex = currentWord.index(currentWord.startIndex, offsetBy: index)
                currentAnswer.text = currentAnswer.text?.replaceSubrange(currentIndex...currentIndex, with: characterString)

                let ranges = currentWord.ranges(of: characterString)
                for range in ranges {
                    currentAnswer.text = currentAnswer.text?.replaceSubrange(range, with: characterString)




    @objc func submitTapped(){




no takers?


@Geeljire wonders:

no takers?

I started looking at this and stopped when I got to the sea of constraints. It was too wide to cross.

It seems your original question about ambiguous subranges may have nothing to do with the interface code.

Can you duplicate the substitution problem in just a few lines of logic code in Playgrounds? Let's focus on the business end of this problem.


currentAnswer.text = currentAnswer.text?.replaceSubrange(currentIndex...currentIndex, with: characterString)
currentAnswer.text = currentAnswer.text?.replaceSubrange(range, with: characterString)

Try breaking these lines up so you aren't trying to do everything in one line.


Hacking with Swift is sponsored by Essential Developer

SPONSORED From March 20th to 26th, you can join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer!

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.