From fef5d15de29b52ee9097259f9024eedda4475b1c Mon Sep 17 00:00:00 2001 From: Mariana Brasil Date: Mon, 24 Oct 2022 22:03:47 -0300 Subject: [PATCH 1/9] Refactor done + fix add new word bug that wouldn't update the words table --- VocabularyTrainer.xcodeproj/project.pbxproj | 16 +- .../xcdebugger/Breakpoints_v2.xcbkptlist | 6 + .../xcschemes/xcschememanagement.plist | 14 ++ .../AddNewWordViewController.swift | 138 ----------- .../AddWord/AddNewWordViewController.swift | 230 ++++++++++++++++++ VocabularyTrainer/Base.lproj/Main.storyboard | 82 +------ VocabularyTrainer/Helper.swift | 1 - .../LanguageScreenViewController.swift | 25 +- 8 files changed, 279 insertions(+), 233 deletions(-) create mode 100644 VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 VocabularyTrainer/AddNewWordViewController.swift create mode 100644 VocabularyTrainer/AddWord/AddNewWordViewController.swift diff --git a/VocabularyTrainer.xcodeproj/project.pbxproj b/VocabularyTrainer.xcodeproj/project.pbxproj index 0f1c8cb..5561889 100644 --- a/VocabularyTrainer.xcodeproj/project.pbxproj +++ b/VocabularyTrainer.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + B3657DFD290740D9000D76C8 /* AddNewWordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3657DFC290740D8000D76C8 /* AddNewWordViewController.swift */; }; CE0012FF2243F21C002F86DE /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0012FE2243F21C002F86DE /* Extensions.swift */; }; CE05F622229F17AF0097E3BB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE05F624229F17AF0097E3BB /* Localizable.strings */; }; CE0FE4F82238585A00430FDE /* TrainingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0FE4F72238585A00430FDE /* TrainingViewController.swift */; }; @@ -20,7 +21,6 @@ CE86C57E2235BDC9008A5B73 /* NewLanguageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE86C57D2235BDC9008A5B73 /* NewLanguageViewController.swift */; }; CE86C5802235C8AD008A5B73 /* LanguageScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE86C57F2235C8AD008A5B73 /* LanguageScreenViewController.swift */; }; CE86C5822235C971008A5B73 /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE86C5812235C971008A5B73 /* Helper.swift */; }; - CE86C584223684D2008A5B73 /* AddNewWordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE86C583223684D2008A5B73 /* AddNewWordViewController.swift */; }; CECD6342235E54350060911F /* pp.html in Resources */ = {isa = PBXBuildFile; fileRef = CECD6344235E54350060911F /* pp.html */; }; CEE4988828F572E200B64FCF /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = CEE4988728F572E200B64FCF /* README.md */; }; E37D16F9261BCBCB006C1F71 /* LanugageTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E37D16F8261BCBCB006C1F71 /* LanugageTableViewCell.swift */; }; @@ -46,6 +46,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + B3657DFC290740D8000D76C8 /* AddNewWordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNewWordViewController.swift; sourceTree = ""; }; CE0012FE2243F21C002F86DE /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; CE05F621229F17830097E3BB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = ""; }; CE05F623229F17AF0097E3BB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -67,7 +68,6 @@ CE86C57D2235BDC9008A5B73 /* NewLanguageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewLanguageViewController.swift; sourceTree = ""; }; CE86C57F2235C8AD008A5B73 /* LanguageScreenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageScreenViewController.swift; sourceTree = ""; }; CE86C5812235C971008A5B73 /* Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helper.swift; sourceTree = ""; }; - CE86C583223684D2008A5B73 /* AddNewWordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNewWordViewController.swift; sourceTree = ""; }; CE92ABF928E97C5600FE2EBC /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = nl; path = nl.lproj/pp.html; sourceTree = ""; }; CE92ABFA28E97CAF00FE2EBC /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; CECD6343235E54350060911F /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = Base; path = Base.lproj/pp.html; sourceTree = ""; }; @@ -104,6 +104,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + B3657DFE290740F8000D76C8 /* AddWord */ = { + isa = PBXGroup; + children = ( + B3657DFC290740D8000D76C8 /* AddNewWordViewController.swift */, + ); + path = AddWord; + sourceTree = ""; + }; CE86C53F2235AE20008A5B73 = { isa = PBXGroup; children = ( @@ -139,7 +147,7 @@ E37D16FD261BCBF9006C1F71 /* Language Screens */, CE86C5812235C971008A5B73 /* Helper.swift */, E37D170A261BCD59006C1F71 /* VocabularyDateFormatter.swift */, - CE86C583223684D2008A5B73 /* AddNewWordViewController.swift */, + B3657DFE290740F8000D76C8 /* AddWord */, CE0FE4F72238585A00430FDE /* TrainingViewController.swift */, CE2EB8262245406A006B1C6D /* Launch Screen.storyboard */, CE05F624229F17AF0097E3BB /* Localizable.strings */, @@ -321,7 +329,7 @@ buildActionMask = 2147483647; files = ( CE86C5802235C8AD008A5B73 /* LanguageScreenViewController.swift in Sources */, - CE86C584223684D2008A5B73 /* AddNewWordViewController.swift in Sources */, + B3657DFD290740D9000D76C8 /* AddNewWordViewController.swift in Sources */, CE86C54E2235AE20008A5B73 /* HomeScreenViewController.swift in Sources */, E37D16FF261BCC10006C1F71 /* VocabularyCell.swift in Sources */, CE0012FF2243F21C002F86DE /* Extensions.swift in Sources */, diff --git a/VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..6928609 --- /dev/null +++ b/VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcschemes/xcschememanagement.plist b/VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..1541d55 --- /dev/null +++ b/VocabularyTrainer.xcodeproj/xcuserdata/marianabrasil.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + VocabularyTrainer.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/VocabularyTrainer/AddNewWordViewController.swift b/VocabularyTrainer/AddNewWordViewController.swift deleted file mode 100644 index 5a2eea8..0000000 --- a/VocabularyTrainer/AddNewWordViewController.swift +++ /dev/null @@ -1,138 +0,0 @@ -// -// AddNewWordViewController.swift -// VocabularyTrainer -// -// Created by skrr on 11.03.19. -// Copyright © 2019 mic. All rights reserved. -// - -import UIKit -import Combine - -class AddNewWordViewController: UIViewController { - - var selectedLanguage: String? - var vocabularies = [String:String]() - var vocabulariesSuccessRates = [String:Float]() - var vocabulariesAddDates = [String:Date]() - var completed: (()->Void)? - - @IBOutlet weak var newWordTextField: UITextField! - @IBOutlet weak var translationTextField: UITextField! - - var newWordHasText = false - var translationHasText = false - - @IBOutlet weak var backButton: UIButton! - @IBOutlet weak var addButton: UIButton! - @IBOutlet weak var addNewWordHeader: UILabel! - override func viewDidLoad() { - super.viewDidLoad() - - print("selected Language: \(String(describing: selectedLanguage))") - hideKeyboardWhenTappedAround() - styleButtons() - localize() - setGradientBackground(view: view) - newWordTextField.text = nil - translationTextField.text = nil - setAddButton(isEnabled: newWordHasText && translationHasText) - - newWordTextField.addTarget(self, action: #selector(textFieldChanged(_:)), for: .editingChanged) - translationTextField.addTarget(self, action: #selector(textFieldChanged(_:)), for: .editingChanged) - } - - @IBAction func backButtonTapped(_ sender: Any) { - completed?() - dismiss(animated: true, completion: nil) - } - - @IBAction func addNewWordTapped(_ sender: Any) { - - guard let language = selectedLanguage else { print("error getting language"); return } - - let languageVocabProgressKey = "\(language)Progress" - let languageVocabDateAddedKey = "\(language)DateAdded" - - if let vocabs = UserDefaults.standard.dictionary(forKey: language) as? [String:String] { - vocabularies = vocabs - } - - if let vocabsSuccess = UserDefaults.standard.dictionary(forKey: languageVocabProgressKey) as? [String:Float] { - vocabulariesSuccessRates = vocabsSuccess - } - - if let vocabsDates = UserDefaults.standard.dictionary(forKey: languageVocabDateAddedKey) as? [String:Date] { - vocabulariesAddDates = vocabsDates - } - - if let word = newWordTextField.text, let translatedWord = translationTextField.text { - vocabularies[word] = translatedWord - vocabulariesSuccessRates[word] = 100 - vocabulariesAddDates[word] = Date() - } - - UserDefaults.standard.set(vocabularies, forKey: language) - UserDefaults.standard.set(vocabulariesSuccessRates, forKey: languageVocabProgressKey) - UserDefaults.standard.set(vocabulariesAddDates, forKey: languageVocabDateAddedKey) - - print( "words: \(String(describing: UserDefaults.standard.dictionary(forKey: language)))") - //dismiss(animated: true, completion: nil) - - newWordTextField.text = "" - translationTextField.text = "" - newWordHasText = false - translationHasText = false - setAddButton(isEnabled: false) - showToast(message: NSLocalizedString("New word added", comment: "New word added"), yCoord: 340.0) - } - - func styleButtons() { - backButton.backgroundColor = BackgroundColor.hansaYellow - backButton.layer.cornerRadius = 5.0 - backButton.contentEdgeInsets = UIEdgeInsets.init(top: 0, left: 10, bottom: 0, right: 10) - backButton.setTitleColor(BackgroundColor.japaneseIndigo, for: .normal) - - setAddButton(isEnabled: true) - } - - func localize() { - backButton.setTitle(NSLocalizedString("< Back", comment: "< Back"), for: .normal) - addButton.setTitle(NSLocalizedString("Add", comment: "Add"), for: .normal) - newWordTextField.placeholder = NSLocalizedString("New word", comment: "new word") - translationTextField.placeholder = NSLocalizedString("translation", comment: "translation") - addNewWordHeader.text = NSLocalizedString("Add new word", comment: "Add new word") - } - - func setAddButton(isEnabled: Bool) { - if isEnabled { - UIView.animate(withDuration: 0.3) { - self.addButton.backgroundColor = BackgroundColor.mediumSpringBud - } - addButton.layer.cornerRadius = 5.0 - addButton.contentEdgeInsets = UIEdgeInsets.init(top: 0, left: 10, bottom: 0, right: 10) - addButton.setTitleColor(.black, for: .normal) - addButton.isEnabled = true - } else { - UIView.animate(withDuration: 0.3) { - self.addButton.backgroundColor = UIColor(red: 207/255, green: 207/255, blue: 205/255, alpha: 0.4) - } - addButton.layer.cornerRadius = 5.0 - addButton.contentEdgeInsets = UIEdgeInsets.init(top: 0, left: 10, bottom: 0, right: 10) - addButton.setTitleColor(.black, for: .normal) - addButton.isEnabled = false - } - } - - @objc func textFieldChanged(_ sender: UITextField) { - let hasText = !(sender.text == nil || sender.text == "") - if sender === newWordTextField { - newWordHasText = hasText - } - - if sender === translationTextField { - translationHasText = hasText - } - setAddButton(isEnabled: newWordHasText && translationHasText) - } -} diff --git a/VocabularyTrainer/AddWord/AddNewWordViewController.swift b/VocabularyTrainer/AddWord/AddNewWordViewController.swift new file mode 100644 index 0000000..89e2181 --- /dev/null +++ b/VocabularyTrainer/AddWord/AddNewWordViewController.swift @@ -0,0 +1,230 @@ +// +// AddNewWordViewController.swift +// VocabularyTrainer +// +// Created by Mariana Brasil on 24/10/22. +// Copyright © 2022 mic. All rights reserved. +// + +import UIKit +import Combine + +final class AddNewWordViewController: UIViewController { + + // MARK: - Private Properties + + private lazy var backButton: UIButton = { + let button = UIButton() + button.setTitle(NSLocalizedString("< Back", comment: "< Back"), for: .normal) + button.backgroundColor = BackgroundColor.hansaYellow + button.layer.cornerRadius = 5.0 + button.contentEdgeInsets = .init(top: 5, left: 10, bottom: 5, right: 10) + button.setTitleColor(BackgroundColor.japaneseIndigo, for: .normal) + button.addTarget(self, action: #selector(didTapBackButton), for: .touchUpInside) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private lazy var addNewWordLabel: UILabel = { + let label = UILabel() + label.text = NSLocalizedString("Add new word", comment: "Add new word") + label.font = UIFont.systemFont(ofSize: 30) + label.textColor = .black + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var newWordTextField: UITextField = { + let textField = UITextField() + textField.placeholder = NSLocalizedString("New word", comment: "new word") + textField.font = UIFont.systemFont(ofSize: 32) + textField.translatesAutoresizingMaskIntoConstraints = false + textField.backgroundColor = .white + textField.layer.cornerRadius = 5.0 + textField.layer.sublayerTransform = CATransform3DMakeTranslation(8, 0, 0) + textField.autocapitalizationType = .none + textField.autocorrectionType = .no + textField.addTarget(self, action: #selector(textFieldChanged), for: .editingChanged) + return textField + }() + + private lazy var translationTextField: UITextField = { + let textField = UITextField() + textField.placeholder = NSLocalizedString("translation", comment: "translation") + textField.font = UIFont.systemFont(ofSize: 32) + textField.translatesAutoresizingMaskIntoConstraints = false + textField.backgroundColor = .white + textField.layer.cornerRadius = 5.0 + textField.layer.sublayerTransform = CATransform3DMakeTranslation(8, 0, 0) + textField.autocapitalizationType = .none + textField.autocorrectionType = .no + textField.addTarget(self, action: #selector(textFieldChanged), for: .editingChanged) + return textField + }() + + private lazy var addButton: UIButton = { + let button = UIButton() + button.setTitle(NSLocalizedString("Add", comment: "Add"), for: .normal) + button.titleLabel?.font = UIFont.systemFont(ofSize: 32) + button.layer.cornerRadius = 5.0 + button.contentEdgeInsets = .init(top: 0, left: 10, bottom: 0, right: 10) + button.setTitleColor(BackgroundColor.japaneseIndigo, for: .normal) + button.addTarget(self, action: #selector(addNewWordTapped), for: .touchUpInside) + button.backgroundColor = UIColor(red: 207/255, green: 207/255, blue: 205/255, alpha: 0.4) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private var selectedLanguage: String? + private var vocabularies = [String:String]() + private var vocabulariesSuccessRates = [String:Float]() + private var vocabulariesAddDates = [String:Date]() + private var newWordHasText = false + private var translationHasText = false + private var completed: (()->Void)? + + // MARK: - Initializer + + init(selectedLanguage: String?) { + super.init(nibName: nil, bundle: nil) + self.selectedLanguage = selectedLanguage + hideKeyboardWhenTappedAround() + setUpUI() + setUpConstraints() + setUpInterfaceStyleUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Private Methods + + private func setUpUI() { + setGradientBackground(view: view) + view.addSubview(backButton) + view.addSubview(addNewWordLabel) + view.addSubview(newWordTextField) + view.addSubview(translationTextField) + view.addSubview(addButton) + } + + private func setUpConstraints() { + backButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 16).isActive = true + backButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true + + addNewWordLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + addNewWordLabel.topAnchor.constraint(equalTo: backButton.bottomAnchor, constant: 16).isActive = true + + newWordTextField.topAnchor.constraint(equalTo: addNewWordLabel.bottomAnchor, constant: 16).isActive = true + newWordTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24).isActive = true + newWordTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24).isActive = true + + translationTextField.topAnchor.constraint(equalTo: newWordTextField.bottomAnchor, constant: 16).isActive = true + translationTextField.leadingAnchor.constraint(equalTo: newWordTextField.leadingAnchor).isActive = true + translationTextField.trailingAnchor.constraint(equalTo: newWordTextField.trailingAnchor).isActive = true + + addButton.topAnchor.constraint(equalTo: translationTextField.bottomAnchor, constant: 24).isActive = true + addButton.leadingAnchor.constraint(equalTo: translationTextField.leadingAnchor).isActive = true + addButton.trailingAnchor.constraint(equalTo: translationTextField.trailingAnchor).isActive = true + } + + private func setUpInterfaceStyleUI() { + switch traitCollection.userInterfaceStyle { + case .light, .unspecified: + addNewWordLabel.textColor = .black + + newWordTextField.backgroundColor = .white + newWordTextField.textColor = .black + + translationTextField.backgroundColor = .white + translationTextField.textColor = .black + case .dark: + addNewWordLabel.textColor = .white + + newWordTextField.backgroundColor = .black + newWordTextField.textColor = .white + + translationTextField.backgroundColor = .black + translationTextField.textColor = .white + } + } + + private func addButtonIsEnabled(_ isEnabled: Bool) { + if isEnabled { + UIView.animate(withDuration: 0.3) { [weak self] in + self?.addButton.backgroundColor = BackgroundColor.mediumSpringBud + } + addButton.isEnabled = isEnabled + } else { + UIView.animate(withDuration: 0.3) { [weak self] in + self?.addButton.backgroundColor = UIColor(red: 207/255, green: 207/255, blue: 205/255, alpha: 0.4) + } + addButton.isEnabled = isEnabled + } + } + + private func wordAddedNotification() { + NotificationCenter.default.post(name: NSNotification.Name(rawValue: "wordAdded"), object: nil) + } + + private func resetConfigs() { + newWordTextField.text = "" + translationTextField.text = "" + newWordHasText = false + translationHasText = false + addButtonIsEnabled(false) + } + + @objc private func didTapBackButton() { + completed?() + dismiss(animated: true) + } + + @objc private func addNewWordTapped() { + guard let language = selectedLanguage, + let word = newWordTextField.text, + let translatedWord = translationTextField.text else { return } + + let languageVocabProgressKey = "\(language)Progress" + let languageVocabDateAddedKey = "\(language)DateAdded" + + if let vocabs = UserDefaults.standard.dictionary(forKey: language) as? [String:String] { + vocabularies = vocabs + } + + if let vocabsSuccess = UserDefaults.standard.dictionary(forKey: languageVocabProgressKey) as? [String:Float] { + vocabulariesSuccessRates = vocabsSuccess + } + + if let vocabsDates = UserDefaults.standard.dictionary(forKey: languageVocabDateAddedKey) as? [String:Date] { + vocabulariesAddDates = vocabsDates + } + + vocabularies[word] = translatedWord + vocabulariesSuccessRates[word] = 100 + vocabulariesAddDates[word] = Date() + + UserDefaults.standard.set(vocabularies, forKey: language) + UserDefaults.standard.set(vocabulariesSuccessRates, forKey: languageVocabProgressKey) + UserDefaults.standard.set(vocabulariesAddDates, forKey: languageVocabDateAddedKey) + + resetConfigs() + wordAddedNotification() + showToast(message: NSLocalizedString("New word added", comment: "New word added"), yCoord: 340.0) + } + + @objc private func textFieldChanged(_ sender: UITextField) { + let hasText = !(sender.text == nil || sender.text == "") + + if sender === newWordTextField { + newWordHasText = hasText + } + + if sender === translationTextField { + translationHasText = hasText + } + + addButtonIsEnabled(newWordHasText && translationHasText) + } +} diff --git a/VocabularyTrainer/Base.lproj/Main.storyboard b/VocabularyTrainer/Base.lproj/Main.storyboard index 5cc90ca..f2a8ae9 100644 --- a/VocabularyTrainer/Base.lproj/Main.storyboard +++ b/VocabularyTrainer/Base.lproj/Main.storyboard @@ -19,6 +19,7 @@