Start 100DaysOfSwiftUI from 2020.Mar.18th.
Day 29, 30, 31: Project 5, part one, two, three
done with 80min
New findings: followings are new findings
- List
- show some rows with data, looks similar to Form, but Form will ask for the input.
- UITextChecker
- for spell checking, but it comes from Objective-C world…
- RoundedBorderTextFieldStyle
- this will show rounded border for TextField
- TextField trainig closure
- it will be called when user press return key, it is same with onCommit
- .autocapitalization
- this modifier can stop “auto-capitalization” feature of textfield
- OnAppear
- looks simlar with viewWillAppear
- fatalError
- in the case no way to continue, fatalError will be the only way we can take.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
struct ContentView: View { @State private var usedWords = [String]() @State private var rootWord = "" @State private var newWord = "" @State private var score = 0 @State private var errorTitle = "" @State private var errorMessage = "" @State private var showingError = false var body: some View { NavigationView { VStack { TextField("Enter your word", text: $newWord, onCommit: addNewWord) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() .autocapitalization(.none) List(usedWords, id:\.self) { Image(systemName: "\($0.count).circle") Text($0) } Text("Score : \(score)") .padding() } .navigationBarTitle(rootWord) .navigationBarItems(leading: Button(action: startGame ) { Text("Restart Game") }) .onAppear(perform: startGame) .alert(isPresented: $showingError) { Alert(title: Text(errorTitle), message: Text(errorMessage), dismissButton: .default(Text("OK"))) } } } func addNewWord() { let answer = newWord.lowercased() .trimmingCharacters(in: .whitespacesAndNewlines) guard answer.count > 0 else { return } guard isOriginal(word: answer) else { wordError(title: "Word used already", message: "Be more original") return } guard isPossible(word: answer) else { wordError(title: "Word not recognized", message: "You can't just make them up, you know!") return } guard isReal(word: answer) else { wordError(title: "Word not possible", message: "That isn't a real word.") return } usedWords.insert(answer, at: 0) newWord = "" score += (answer.count)*(answer.count) } func startGame() { usedWords = [] score = 0 if let startTxtUrl = Bundle.main.url(forResource: "start", withExtension: "txt") { if let startWords = try? String(contentsOf: startTxtUrl) { let allWords = startWords.components(separatedBy: "\n") rootWord = allWords.randomElement() ?? "silkworm" return } } fatalError("Could not load start.txt from bundle.") } func isOriginal(word: String) -> Bool { !usedWords.contains(word) } func isPossible(word: String) -> Bool { var tempWord = rootWord for letter in word { if let pos = tempWord.firstIndex(of: letter) { tempWord.remove(at: pos) } else { return false } } return true } func isReal(word: String) -> Bool { if word.count < 3 { return false} if word == rootWord { return false } let checker = UITextChecker() let range = NSRange(location: 0, length: word.utf16.count) let missspelledRange = checker.rangeOfMisspelledWord(in: word, range: range, startingAt: 0, wrap: false, language: "en") return missspelledRange.location == NSNotFound } func wordError(title: String, message: String) { errorTitle = title errorMessage = message showingError = true } } |
Sponsor Link