Swift 点击UINavigationController UINavigationTabBar项时如何调用函数?

Swift 点击UINavigationController UINavigationTabBar项时如何调用函数?,swift,uinavigationcontroller,uinavigationbar,Swift,Uinavigationcontroller,Uinavigationbar,我希望能够在用户点击UINavigationController UINavigationTabBar项时显示UIAlertAction,以提醒他们在进入下一个UIViewController之前需要输入一些信息,否则将通过点击调用该UIViewController。从tap调用的代码将检查数组是否为空,如果为空,则显示UIAlertAction 我曾尝试创建UINavigationController的UINavigationTabBar项的实例,以尝试检测它是否被推送,但这很混乱,因为当点击

我希望能够在用户点击UINavigationController UINavigationTabBar项时显示UIAlertAction,以提醒他们在进入下一个UIViewController之前需要输入一些信息,否则将通过点击调用该UIViewController。从tap调用的代码将检查数组是否为空,如果为空,则显示UIAlertAction

我曾尝试创建UINavigationController的UINavigationTabBar项的实例,以尝试检测它是否被推送,但这很混乱,因为当点击UINavigationTabBar项时,要调用的UIViewController已经设置为segue


我是否需要回溯并删除现有segue,并以不同的方式创建转换,以允许在用户点击时调用所需的数组检查代码?

如果您正在使用segue推送下一个视图控制器,您将拦截该segue,执行所有检查,然后通知segue是继续推送还是取消推送。基本上在视图控制器中:

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if identifier == "NextViewControllerID" {
        var isValid = true

        // example of validation, do your stuff here
        if myTextField.text?.count ?? 0 < 5 {
            isValid = false
        }

        return isValid
    }
    // otherwise delegates the superclass
    return super.shouldPerformSegue(withIdentifier: identifier, sender: sender)
}

override func shouldPerformSegue(标识符:String,发送方:Any?)->Bool{
如果标识符==“NextViewControllerID”{
var isValid=true
//验证示例,请在此处完成您的工作
如果myTextField.text?.count?0小于5{
isValid=false
}
返回有效
}
//否则将委托超类
返回super.shouldPerformSegue(带标识符:标识符,发件人:发件人)
}

那么您已将显示配置为segue?什么是
UINavigationTabBar
?没有这样的事。请回答您的问题并澄清您真正的意思。我已将identifier设置为Words(在故事板中转换下一个视图控制器id,单词与要转换到的下一个视图控制器相关)。只是不确定“withIdentifier:”Segue即使在验证为false(空数组)时也会发生。确保返回false如果验证不为ok返回false当数组为空时,返回true is identifier是下一个视图控制器的Segue标识符。我不认为布尔值是问题所在。如果如果标识符是要转到的视图控制器的标识符,则返回true,则显然触发了segue。发布新代码请跳过func shouldPerformSegue(带有标识符:String,sender:Any?->Bool{if identifier==“Words”{var isValid=true if languages.isEmpty==true{isValid=false}返回isValid}//否则,将委托超类返回super.shouldPerformSegue(带标识符:identifier,发送者:发送者)}
import UIKit

class WordsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    // write button selector method to check if there are any words.

    var words = [String]()
    var languages = [String]()
    var chosenLanguage = String()
    var textField: UITextField?
    let wordString = "Words"

    override func viewDidLoad() {
        super.viewDidLoad()

        chosenLanguageLoad()
        loadInitialValues()

        //let titleAttributes = [NSAttributedString.Key.font: UIFont(name: "AmericanTypewriter", size: 22)!]
        //navigationController?.navigationBar.titleTextAttributes = titleAttributes

        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(test))

        navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addNewWord))

        print("languages array is: \(languages)")
    }

    override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
        if identifier == "Words" {
            print("inside identifier == words if")
            var isValid = true
            if languages.isEmpty == true {
                print("languages is empty is true")
                isValid = false
            }

            return isValid
        }
        // otherwise delegates the superclass
        return super.shouldPerformSegue(withIdentifier: identifier, sender: sender)
    }

    @objc func test() {
        if words.isEmpty == true {
            let ac = UIAlertController(title: "Add Some Words", message: nil, preferredStyle: .alert)
            let okAction = UIAlertAction(title: "OK", style: .default)
            ac.addAction(okAction)
            present(ac, animated: true)
        } else {
            self.performSegue(withIdentifier: "Test", sender: self)
        }
    }

    func chosenLanguageLoad() {
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.polyglot") {
            if let loadChosenLanguage = defaults.object(forKey: "languageChosen") as? String {
                chosenLanguage = loadChosenLanguage
                print("Chosen language is: \(chosenLanguage)")
            }
        }
    }

    @objc func loadInitialValues() {
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.polyglot") {
            words.removeAll()
            tableView.reloadData()
            print("Words array after clear all: \(words)")
            print("chosenLanguage in loadInitialValues: \(chosenLanguage)")
            print("\(chosenLanguage)\(wordString)")
            if var savedWords = defaults.object(forKey: "\(chosenLanguage)\(wordString)") as? [String] {
                print("savedWords array is: \(savedWords)")
                words = savedWords
                savedWords.removeAll()
                print("savedWords array after clear all: \(savedWords)")
            } else {
                saveInitialWordValues(to: defaults)
            }
            print("Words is : \(words)")
            print("Number of words: \(words.count)")
            tableView.reloadData()
        }
    }

    func saveInitialWordValues(to defaults: UserDefaults) {
        switch chosenLanguage {
        case "german":
            words.append("Bear::Baissespekulant::0")
            words.append("Camel::Kamel::0")
            words.append("Cow::Rind::0")
            words.append("Fox::Fuchs::0")
            words.append("Goat::Geiß::0")
            words.append("Monkey::Affe::0")
            words.append("Pig::Schwein::0")
            words.append("Rabbit::Karnickel::0")
            words.append("Sheep::Schaf::0")
            //words.append("::")
            print(words)
            defaults.set(words, forKey: "germanWords")
            print("At end of saveInitialGermanValues")
        case "french":
            words.append("Bear::l'ours::0")
            words.append("Camel::le chameau::0")
            words.append("Cow::la vache::0")
            words.append("Fox::le renard::0")
            words.append("Goat::la chèvre::0")
            words.append("Monkey::le singe::0")
            words.append("Pig::le cochon::0")
            words.append("Rabbit::le lapin::0")
            words.append("Sheep::le mouton::0")
            //words.append("::")
            print(words)
            defaults.set(words, forKey: "frenchWords")
            print("At end of saveInitialFrenchValues")
        default:
            break
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        chosenLanguageLoad()
        loadInitialValues()
    }

    override func viewDidAppear(_ animated: Bool) {

        navigationController?.setToolbarHidden(true, animated: false)

        super.viewDidAppear(animated)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }

    @objc func addNewWord() {
        // create our alert controller
        let ac = UIAlertController(title: "Add new word", message: nil, preferredStyle: .alert)

        // add two text fields, one for English and one for French or German.
        ac.addTextField { textField in
            textField.placeholder = "English"
        }

        ac.addTextField { (textField) in
            textField.placeholder = "\(self.chosenLanguage.capitalized)"
        }

        // create an "Add Word" button that submits the user's input
        let submitAction = UIAlertAction(title: "Add Word", style: .default) { [unowned self, ac] (action: UIAlertAction!) in
            // pull out the English and French words, or an empty string if there was a problem
            let firstWord = ac.textFields?[0].text ?? ""
            let secondWord = ac.textFields?[1].text ?? ""
            let zeroTimesWrong = "0"
            // submit the English and French word to the insertFlashcard() method
            self.insertFlashcard(first: firstWord, second: secondWord, third: zeroTimesWrong)
        }

        // add the submit action, plus a cancel button
        ac.addAction(submitAction)
        ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))

        // present the alert controller to the user
        present(ac, animated: true)
    }

    func insertFlashcard(first: String, second: String, third: String) {
        guard first.count > 0 && second.count > 0 else { return }

        let newIndexPath = IndexPath(row: words.count, section: 0)

        words.append("\(first)::\(second)::\(third)")
        tableView.insertRows(at: [newIndexPath], with: .automatic)

        saveWords()
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        let delete  = UITableViewRowAction(style: .default, title: "Delete") { action, indexPath in
            self.words.remove(at: indexPath.row)
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .left)
            tableView.endUpdates()
            // delete item at indexPath
        }

        let edit = UITableViewRowAction(style: .normal, title: "Edit") { (action, indexPath) in
            let ac = UIAlertController(title: "Edit word", message: nil, preferredStyle: .alert)

            // add two text fields, one for English and one for French
            ac.addTextField { textField in
                let word = self.words[indexPath.row]
                let split = word.components(separatedBy: "::")
                let englishWord = split[0]
                textField.placeholder = "\(englishWord)"
            }

            ac.addTextField { (textField) in
                let word = self.words[indexPath.row]
                let split = word.components(separatedBy: "::")
                let foreignWord = split[1]
                textField.placeholder = "\(foreignWord)"
            }

            // create an "Add Word" button that submits the user's input
            let submitAction = UIAlertAction(title: "Edit Word", style: .default) { [unowned self, ac] (action: UIAlertAction!) in
                // pull out the English and French words, or an empty string if there was a problem
                let firstWord = ac.textFields?[0].text ?? ""
                let secondWord = ac.textFields?[1].text ?? ""

                guard firstWord.count > 0 && secondWord.count > 0 else { return }
                // edit item at indexPath
                self.words.remove(at: indexPath.row)
                self.words.insert("\(firstWord)::\(secondWord)", at: indexPath.row)
                tableView.beginUpdates()
                tableView.deleteRows(at: [indexPath], with: .automatic)
                tableView.insertRows(at: [indexPath], with: .automatic)
                tableView.endUpdates()

                self.saveWords()
            }

            // add the submit action, plus a cancel button
            ac.addAction(submitAction)
            ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))

            // present the alert controller to the user
            self.present(ac, animated: true)
        }

        edit.backgroundColor = UIColor.blue

        return [delete, edit]
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return words.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //print("In cellForRowAt function")
        let cell = tableView.dequeueReusableCell(withIdentifier: "Word", for: indexPath)

        let word = words[indexPath.row]
        if word != "::" {
            let split = word.components(separatedBy: "::")

            print(split[0])

            cell.textLabel?.text = split[0]

            cell.detailTextLabel?.text = ""

            //print(cell)
        }
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        if let cell = tableView.cellForRow(at: indexPath) {
            if cell.detailTextLabel?.text == "" {
                let word = words[indexPath.row]
                let split = word.components(separatedBy: "::")
                cell.detailTextLabel?.text = split[1]
            } else {
                cell.detailTextLabel?.text = ""
            }
        }
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        words.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .automatic)
        saveWords()
    }

    func saveWords() {
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.polyglot") {
            defaults.set(words, forKey: "\(chosenLanguage)\(wordString)")
        }
    }
}