不要在UITextField返回上关闭键盘

时间:2019-08-22 15:57:18

标签: ios swift keyboard uitextfield

我见过的每一篇帖子都希望在用户完成UITextField编辑后关闭键盘。我发现每次想要再次开始编辑以重新出现键盘时都必须点按UITextField,这很烦人。我需要始终保持键盘向上,以便在键入开始后立即开始下一次用户输入。

当前,如果在textFieldShouldReturn-> true UITextFieldDelegate方法中调用了UITextField resignFirstResponder方法,则我的代码只能对用户键盘输入起作用。

我尝试了以下方法:

func textFieldShouldEndEditing(_ textField:UITextField)-> Bool {         假     }

//
//  TestViewController.swift
//  Hyperpolyglot
//
//  Created by Alan Dripps on 10/02/2019.
//  Copyright © 2019 Alan Dripps. All rights reserved.
//

import UIKit
import AVFoundation

class TestViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var stackView: UIStackView!
    @IBOutlet weak var prompt: UILabel!
    @IBOutlet weak var synthesizeButton: UIButton!
    @IBOutlet weak var instructions: UILabel!
    @IBOutlet weak var englishAnswer: UITextField!

    var words = [String]()
    var testWords = [String]()
    var useHomework: Bool!
    var practiceWrongNoCorrectAnswer: Int!
    var homeworkWrongNoCorrectAnswer: Int!
    var questionCounter = 0
    var showingQuestion = true
    var chosenLanguage = String()
    var language = String()
    let wordsString = "Words"
    var englishWord = String()
    var foreignWord = String()
    var attempted = Int()
    var homeworkAttempted = Int()
    var homework = Int()

    override func viewDidLoad() {
        super.viewDidLoad()

        print("viewDidLoad questionCounter is: \(questionCounter)")
        print("useHomework in viewDidLoad in TestViewController is: \(useHomework!)")

        loadChosenLanguage()
        loadWords()
        print("testWords just before shuffle: \(testWords)")
        testWords.shuffle()
        print("testWords just after shuffle: \(testWords)")

        if useHomework == true {
            navigationItem.title = "Learn Homework"
        } else {
            navigationItem.title = "Learn \(chosenLanguage.capitalized)"
        }
        navigationItem.rightBarButtonItem =
            UIBarButtonItem(title: "Reveal Answer", style: .plain , target: self, action: #selector(answerTapped))

        stackView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        stackView.alpha = 0

        synthesizeButton.isEnabled = false
        synthesizeButton.alpha = 0.25
        englishAnswer.delegate = self
        englishAnswer.layer.cornerRadius = 0.05 * englishAnswer.bounds.size.width
        let placeholderColor = UIColor.systemGray
        englishAnswer.attributedPlaceholder = NSAttributedString(string: "Tap here to answer", attributes: [NSAttributedString.Key.foregroundColor : placeholderColor])
        askQuestion()

        instructions.isHidden = true
    }

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

        //loadWords()
        //print("testWords just before shuffle: \(testWords)")
        //testWords.shuffle()
        //print("testWords just after shuffle: \(testWords)")
        //print("questionCounter in viewWillAppear in TestViewController is: \(questionCounter)")
        englishAnswer.delegate = self
        englishAnswer.returnKeyType = .done
    }

    func textFieldShouldReturn(_ englishAnswer: UITextField) -> Bool {
        //englishAnswer.resignFirstResponder()
        self.englishAnswer(englishAnswer)
        return true
    }

    @IBAction func synthesizeButton(_ sender: UIButton) {
        let utterance = AVSpeechUtterance(string: testWords[questionCounter].components(separatedBy: "::")[0])
        utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
        utterance.rate = 0.5

        let synthesizer = AVSpeechSynthesizer()
        synthesizer.speak(utterance)
    }

    @IBAction func englishAnswer(_ sender: UITextField) {
        print("Entered englishAnswer")
        let trimmed = sender.text?.trimmingCharacters(in: .whitespacesAndNewlines)
        print("trimmed?capitalized in englishAnswer in TestViewController is: \(trimmed?.capitalized ?? "")")
        if trimmed?.capitalized == testWords[questionCounter].components(separatedBy: "::")[0] {
            resetWordCounters()
            if questionCounter + 1 < testWords.count {
                questionCounter += 1
            } else {
                questionCounter = 0
            }

            if case prompt.textColor = UIColor(red: 0, green: 0.7, blue: 0, 
                    alpha: 1) {
                print("prompt.textColor in englishAnswer in 
                TestViewController is: \(prompt.textColor!)")
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                self.prepareForNextQuestion()
            }
        } else {
            appendPracticeWord()
            prompt.textColor = UIColor(red: 0.7, green: 0, blue: 0, alpha: 1)
            synthesizeButton.isEnabled = true
            synthesizeButton.alpha = 1
            instructions.isHidden = false
        }
        englishAnswer.text?.removeAll()
        englishAnswer.placeholder = nil
        englishAnswer.isEnabled = false
        englishAnswer.layer.borderColor = UIColor.lightGray.cgColor as CGColor
    }

    func loadChosenLanguage() {
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
            if let savedChosenLanguage = defaults.object(forKey: "languageChosen") as? String {
                print("savedChosen Language in loadChosenLanguage in TestViewController is: \(savedChosenLanguage)")
                chosenLanguage = savedChosenLanguage
            }
        }
    }

    func loadWords() {
        print("in loadWords in TestViewController")
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
            print("after defaults in loadWords in TestViewController")
            if var savedWords = defaults.object(forKey: "words") as? [String] {
                words.removeAll()
                testWords.removeAll()
                words = savedWords
                print("savedWords in loadWords in TestViewcontroller are: \(savedWords)")
                print("words in loadWords in TestViewController are: \(words)")
                for savedWord in savedWords {
                    let split = savedWord.components(separatedBy: "::")
                    if useHomework == false {
                        if split[7] == chosenLanguage {
                            testWords.append(savedWord)
                            print("testWords.append from chosenLanguage in loadWords in TestViewController are: \(testWords)")
                        }
                    } else {
                        if split[6] == "1" {
                            testWords.append(savedWord)
                            print("testWords.append from homework in loadWords in TestViewController are: \(testWords)")
                        }
                    }
                }
                savedWords.removeAll()
            }
        }
    }

    override func viewDidLayoutSubviews() {
        //configureButtons()
    }

    func configureButtons() {
        synthesizeButton.layer.cornerRadius = 0.5 * synthesizeButton.bounds.size.width
        synthesizeButton.layer.borderColor = UIColor.lightGray.cgColor as CGColor
        synthesizeButton.layer.borderWidth = 4.0
        synthesizeButton.clipsToBounds = true
    }

    func resetWordCounters() {
        print("questionCounter in resetWordCounters in TestViewController is: \(questionCounter)")
        let resetCountersWord = testWords[questionCounter].components(separatedBy: "::")[1]
        print("resetCountersWord in resetWordCounters in TestViewController is: \(resetCountersWord)")
        if useHomework == false {
            attempted += 1
        } else {
            homeworkAttempted += 1
        }
        if useHomework == false {
            practiceWrongNoCorrectAnswer = 0
        } else {
            homeworkWrongNoCorrectAnswer = 0
        }

        var indexForTestWord = 0
        for testWord in testWords {
            if testWord.components(separatedBy: "::")[1] == resetCountersWord {
                print("testWord equals resetCountersWord: \(resetCountersWord)")
                let split = testWord.components(separatedBy: "::")
                let firstWord = split[0]
                let secondWord = split[1]
                testWords.remove(at: indexForTestWord)
                print("testWords.remove in resetWordCounters in TestViewController are: \(testWords)")
            testWords.insert("\(firstWord)"+"::"+"\(secondWord)"+"::"+"\(practiceWrongNoCorrectAnswer!)"+"::"+"\(homeworkWrongNoCorrectAnswer!)"+"::"+"\(attempted)"+"::"+"\(homeworkAttempted)"+"::"+"\(homework)"+"::"+"\(language)", at: indexForTestWord)
                print("testWords.insert in resetWordCounters in TestViewController: \(testWords)")
                break
            }
            indexForTestWord += 1
        }
        print("indexForTestWord in resetWordCounters in TestViewController is: \(indexForTestWord)")

        removeInsertWord(resetCountersWordPracticeWord: resetCountersWord)
    }

    func appendPracticeWord() {
        if useHomework == false {
            attempted += 1
        } else {
            homeworkAttempted += 1
        }
        if useHomework == false {
            practiceWrongNoCorrectAnswer += 1
        } else {
            homeworkWrongNoCorrectAnswer += 1
        }

        print("questionCounter in appendPracticeWord in TestViewController is: \(questionCounter)")

        let practiceWord = testWords[questionCounter].components(separatedBy: "::")[1]
        print("practiceWord in appendPracticeWord in TestViewController is: \(practiceWord)")

        var indexForPracticeWord = 0
        for testWord in testWords {
            if testWord.components(separatedBy: "::")[1] == practiceWord {
                print("testWord equals practiceWord: \(practiceWord)")
                let split = testWord.components(separatedBy: "::")
                let firstWord = split[0]
                let secondWord = split[1]
                testWords.remove(at: indexForPracticeWord)
                print("testWords.remove in appendPracticeWord in TestViewController: \(testWords)")
            testWords.insert("\(firstWord)"+"::"+"\(secondWord)"+"::"+"\(practiceWrongNoCorrectAnswer!)"+"::"+"\(homeworkWrongNoCorrectAnswer!)"+"::"+"\(attempted)"+"::"+"\(homeworkAttempted)"+"::"+"\(homework)"+"::"+"\(language)", at: indexForPracticeWord)
                print("testWords.insert in appendPracticeWord in TestViewController: \(testWords)")
                break
            }
            indexForPracticeWord += 1
        }

        print("indexForPracticeWord in appendPracticeWord in TestViewController is: \(indexForPracticeWord)")

        removeInsertWord(resetCountersWordPracticeWord: practiceWord)
    }

    func removeInsertWord(resetCountersWordPracticeWord: String) {
        var indexForWord = 0
        for word in words {
            if word.components(separatedBy: "::")[1] == resetCountersWordPracticeWord {
                print("word equals resetCountersWordPracticeWord: \(word)")
                let split = word.components(separatedBy: "::")
                let firstWord = split[0]
                let secondWord = split[1]
                words.remove(at: indexForWord)
                print("words.remove in removeInsertWord in TestViewController are: \(words)")
            words.insert("\(firstWord)"+"::"+"\(secondWord)"+"::"+"\(practiceWrongNoCorrectAnswer!)"+"::"+"\(homeworkWrongNoCorrectAnswer!)"+"::"+"\(attempted)"+"::"+"\(homeworkAttempted)"+"::"+"\(homework)"+"::"+"\(language)", at: indexForWord)
                print("words.insert in removeInsertWord in TestViewController after insert: \(words)")
                break
            }
            indexForWord += 1
        }

        print("indexForWord in removeInsertWord in TestViewController is: \(indexForWord)")

        saveWords()
    }

    @objc func answerTapped() {
        showEnglishQuestion()
    }

    func showEnglishQuestion() {
        showingQuestion = !showingQuestion
        if showingQuestion {
            // we should be showing the question – reset!
            prepareForNextQuestion()
            navigationItem.rightBarButtonItem =
                UIBarButtonItem(title: "Reveal Answer", style: .plain , target: self, action: #selector(answerTapped))

            //englishAnswer.isEnabled = true
        } else {
            // we should be showing the answer – show it now, and set the color to be green
            print("questionCounter before prompt.text in showEnglishQuestion in TestViewController is: \(questionCounter)")
            prompt.text = testWords[questionCounter].components(separatedBy: "::")[0]
            prompt.textColor = UIColor(red: 0, green: 0.7, blue: 0, alpha: 1)
            print("testWords.count in askQuestion in TestViewController is: \(testWords.count)")
            if questionCounter + 1 < testWords.count {
                let showNextLanguage = testWords[questionCounter + 1] .components(separatedBy: "::")[7]
                navigationItem.rightBarButtonItem =
                    UIBarButtonItem(title: "Next \(showNextLanguage.capitalized) Word", style: .plain , target: self, action: #selector(answerTapped))
                print("showNextLanguage in showEnglishQuestion in TestViewController is: \(showNextLanguage)")
                // move the question counter one place
                questionCounter += 1
                print("questionCounter in showEnglishQuestion in TestViewController is: \(questionCounter)")
            } else {
                // wrap it back to 0 if we've gone beyond the size of the array
                questionCounter = 0
                print("questionCounter in questionCounter = 0 else statement in showEnglishQuestion in TestViewController is: \(questionCounter)")
                print("words array in showEnglishQuestion in TestViewController when questionCounter = 0 is: \(testWords)")
                let showNextLanguage = testWords[questionCounter] .components(separatedBy: "::")[7]
                navigationItem.rightBarButtonItem =
                    UIBarButtonItem(title: "Next \(showNextLanguage.capitalized) Word", style: .plain , target: self, action: #selector(answerTapped))
                print("showNextLanguage in if questionCounter == 0 in showEnglishQuestion in TestViewController is: \(showNextLanguage)")
                // move the question counter one place
            }
            englishAnswer.isEnabled = false
        }
        synthesizeButton.isEnabled = false
        synthesizeButton.alpha = 0.25
        instructions.isHidden = true
    }

    func askQuestion() {
        // pull out the foreign word at the current question position
        print("questionCounter before prompt.text in askQuestion in TestViewController is: \(questionCounter)")
        prompt.text = testWords[questionCounter].components(separatedBy: "::")[1]
        print("testWords[questionCounter] in askQuestion in TestViewController is: \(testWords[questionCounter].components(separatedBy: "::")[0])")

        let animation = UIViewPropertyAnimator(duration: 0.5, dampingRatio: 0.5) {
            self.stackView.alpha = 1
            self.stackView.transform = CGAffineTransform.identity
        }
        animation.startAnimation()

        englishAnswer.isEnabled = true
        englishAnswer.layer.borderColor = UIColor.black.cgColor as CGColor

        englishWord = testWords[questionCounter].components(separatedBy: "::")[0]
        foreignWord = testWords[questionCounter].components(separatedBy: "::")[1]
        practiceWrongNoCorrectAnswer = Int(testWords[questionCounter].components(separatedBy: "::")[2])!
        homeworkWrongNoCorrectAnswer = Int(testWords[questionCounter].components(separatedBy: "::")[3])!
        attempted = Int(testWords[questionCounter].components(separatedBy: "::")[4])!
        homeworkAttempted = Int(testWords[questionCounter].components(separatedBy: "::")[5])!
        homework = Int(testWords[questionCounter].components(separatedBy: "::")[6])!
        language = testWords[questionCounter].components(separatedBy: "::")[7]
    }

    func prepareForNextQuestion() {
        let animation = UIViewPropertyAnimator(duration: 0.5, curve: .easeInOut) { [unowned self] in
            self.stackView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
            self.stackView.alpha = 0
        }

        animation.addCompletion { [unowned self] position in
            self.prompt.textColor = UIColor.black
            self.askQuestion()
        }

        animation.startAnimation()

        englishAnswer.placeholder = "Tap here to answer"
    }

    func saveWords() {
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.hyperpolyglot.todayview") {
            defaults.set(words, forKey: "words")
        }
    }

    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destination.
     // Pass the selected object to the new view controller.
     }
     */
}

textFieldShouldEndEditing方法停止了键盘的释放,但没有将用户的编辑传递给我的发件人:UITextField方法,该方法对输入有帮助。

2 个答案:

答案 0 :(得分:0)

请在故事板上的视图控制器中添加文本字段的委托,或在viewDidLoad中设置“ englishAnswer.delegate = self”

不要尝试在textFieldShouldReturn中返回false。它不会做任何改变。

答案 1 :(得分:0)

现在我很明白你的意思了。您所做的一切都是正确的。然后在textFieldShouldEndEditing或textFieldShouldReturn中手动调用方法“ self.englishAnswer(_ sender:textField)。然后它将起作用。您没有在任何地方调用该方法。