Q:

Maximum one checkmark in TableView in Swift

I would like that users can choose maximum one voice. And that the checkmark jumps to where you tapt and deselect the other.
It looks like very simple, but I don't see the solution. And I can't find the answer on the internet.
Please can anybody help me?
Thanks advance!
import UIKit
import AVFoundation

class voicesTableViewController: UITableViewController  {

    fileprivate let synthesizer = AVSpeechSynthesizer()
    fileprivate var speechVoices = AVSpeechSynthesisVoice.speechVoices()

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return speechVoices.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        //Name
        let voice = speechVoices[indexPath.row]
        let voiceLang = voice.language as? String
        let theVoice = UserDefaults.standard.object(forKey:"voice") as? String

        cell.textLabel?.text = voice.name

        // Language
        if let language = countryName(countryCode: voice.language) {
            cell.detailTextLabel?.text = "\(language)"
        }
        else {
            cell.detailTextLabel?.text = ""
        }

        cell.detailTextLabel?.textColor = UIColor.gray

        // Checkmark

        if (theVoice != nil) {
            if(theVoice == voiceLang) {
                cell.accessoryType = UITableViewCellAccessoryType.checkmark
            }
        }

        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let voice = speechVoices[indexPath.row]

        if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCellAccessoryType.checkmark {
            tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.none
        }
        else
        {
            //if ((tableView.indexPathsForSelectedRows?.count)! > 1) {
                tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.checkmark
            //}
        }

        UserDefaults.standard.set(voice.language, forKey:"voice")
        UserDefaults.standard.synchronize()

        tableView.deselectRow(at: indexPath, animated: true)
    }

    func countryName(countryCode: String) -> String? {
        let preferredLanguage = NSLocale.preferredLanguages[0] as String
        let current = Locale(identifier: preferredLanguage)
        return current.localizedString(forLanguageCode: countryCode) ?? nil

        //return current.localizedString(forIdentifier: indentifier) ? nil
    }

}

A:

Simple change of function cellForRow:atIndexPathshould work:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    //Name
    let voice = speechVoices[indexPath.row]
    let voiceLang = voice.language as? String
    let theVoice = UserDefaults.standard.object(forKey:"voice") as? String

    cell.textLabel?.text = voice.name

    // Language
    if let language = countryName(countryCode: voice.language) {
        cell.detailTextLabel?.text = "\(language)"
    }
    else {
        cell.detailTextLabel?.text = ""
    }

    cell.detailTextLabel?.textColor = UIColor.gray

    // Checkmark

    if(theVoice != nil && theVoice == voiceLang) {
        cell.accessoryType = .checkmark
    } else {
        cell.accessoryType = .none
    }

    return cell
}

UPD#1
But you can use better solution:
1) Add property fileprivate var selectedIndexPath: IndexPath?
2) Change function func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)to next one:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        //Name
        let voice = speechVoices[indexPath.row]
        let voiceLang = voice.language as? String
        let theVoice = UserDefaults.standard.object(forKey:"voice") as? String

        cell.textLabel?.text = voice.name

        // Language
        if let language = countryName(countryCode: voice.language) {
            cell.detailTextLabel?.text = "\(language)"
        }
        else {
            cell.detailTextLabel?.text = ""
        }

        cell.detailTextLabel?.textColor = UIColor.gray

        // Checkmark
        cell.accessoryType = self.selectedIndexPath == indexPath ? .checkmark : .none
        return cell
    }

3) And then in func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) you can do next:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let voice = speechVoices[indexPath.row]

        self.selectedIndexPath = indexPath
        UserDefaults.standard.set(voice.language, forKey:"voice")
        UserDefaults.standard.synchronize()

        tableView.deselectRow(at: indexPath, animated: true)
        tableView.reloadRows(at: [indexPath], with: .automatic)
    }

