diff --git a/Keyboards/KeyboardsBase/Colors/ColorVariables.swift b/Keyboards/KeyboardsBase/Colors/ColorVariables.swift index 72e5f1be..366b5c78 100644 --- a/Keyboards/KeyboardsBase/Colors/ColorVariables.swift +++ b/Keyboards/KeyboardsBase/Colors/ColorVariables.swift @@ -30,10 +30,10 @@ var keyPressedColor = UIColor(.keyPressed) var commandKeyColor = UIColor(.commandKey) var commandBarColor = UIColor(.commandBar) -var commandBarBorderColor = UIColor(.commandBarBorder).cgColor +var commandBarBorderColor = UIColor(resource: .commandBarBorder).cgColor var keyboardBgColor = UIColor(.keyboardBackground) -var keyShadowColor = UIColor(.keyShadow).cgColor +var keyShadowColor = UIColor(resource: .keyShadow).cgColor // annotate colors. var annotateRed = UIColor(.annotateRed) diff --git a/Keyboards/KeyboardsBase/InterfaceVariables.swift b/Keyboards/KeyboardsBase/InterfaceVariables.swift index 55c98525..d70d9698 100644 --- a/Keyboards/KeyboardsBase/InterfaceVariables.swift +++ b/Keyboards/KeyboardsBase/InterfaceVariables.swift @@ -202,8 +202,7 @@ func setKeyboard() { func setKeyboardLayout() { if commandState == .translate { setENKeyboardLayout() - } else { - let setLayoutFxn: () -> Void = keyboardLayoutDict[controllerLanguage]! + } else if let setLayoutFxn = keyboardLayoutDict[controllerLanguage] { setLayoutFxn() } diff --git a/Keyboards/KeyboardsBase/KeyAltChars.swift b/Keyboards/KeyboardsBase/KeyAltChars.swift index 9885a428..2f99b178 100644 --- a/Keyboards/KeyboardsBase/KeyAltChars.swift +++ b/Keyboards/KeyboardsBase/KeyAltChars.swift @@ -329,50 +329,51 @@ func alternateKeysPathRight( /// - sender: the long press of the given key. func genAlternatesView(key: UIButton) { // Get the frame in respect to the superview. - let frame = (key.superview?.convert(key.frame, to: nil))! - let width = key.frame.width - - // Derive which button was pressed and get its alternates. - let char = key.layer.value(forKey: "original") as? String ?? "" - alternateKeys = keyAlternatesDict[char] ?? [""] - - // Add the original key given its location on the keyboard. - if keysWithAlternatesLeft.contains(char) { - alternateKeys.insert(char, at: 0) - } else if keysWithAlternatesRight.contains(char) { - alternateKeys.append(char) - } - let numAlternates = CGFloat(alternateKeys.count) - - if keysWithAlternatesLeft.contains(char) { - alternatesViewX = frame.origin.x - 4.0 - alternatesShapeLayer.path = alternateKeysPathLeft( - startX: frame.origin.x, startY: frame.origin.y, - keyWidth: width, keyHeight: key.frame.height, numAlternates: numAlternates - ).cgPath - } else if keysWithAlternatesRight.contains(char) { - alternatesViewX = frame.origin.x + width - CGFloat(width * numAlternates + (3.0 * numAlternates) + 2.0) - alternatesShapeLayer.path = alternateKeysPathRight( - startX: frame.origin.x, startY: frame.origin.y, - keyWidth: width, keyHeight: key.frame.height, numAlternates: numAlternates - ).cgPath - } + if let frame = key.superview?.convert(key.frame, to: nil) { + let width = key.frame.width + + // Derive which button was pressed and get its alternates. + let char = key.layer.value(forKey: "original") as? String ?? "" + alternateKeys = keyAlternatesDict[char] ?? [""] + + // Add the original key given its location on the keyboard. + if keysWithAlternatesLeft.contains(char) { + alternateKeys.insert(char, at: 0) + } else if keysWithAlternatesRight.contains(char) { + alternateKeys.append(char) + } + let numAlternates = CGFloat(alternateKeys.count) + + if keysWithAlternatesLeft.contains(char) { + alternatesViewX = frame.origin.x - 4.0 + alternatesShapeLayer.path = alternateKeysPathLeft( + startX: frame.origin.x, startY: frame.origin.y, + keyWidth: width, keyHeight: key.frame.height, numAlternates: numAlternates + ).cgPath + } else if keysWithAlternatesRight.contains(char) { + alternatesViewX = frame.origin.x + width - CGFloat(width * numAlternates + (3.0 * numAlternates) + 2.0) + alternatesShapeLayer.path = alternateKeysPathRight( + startX: frame.origin.x, startY: frame.origin.y, + keyWidth: width, keyHeight: key.frame.height, numAlternates: numAlternates + ).cgPath + } - if numAlternates > 0 { - alternatesViewWidth = CGFloat(width * numAlternates + (3.0 * numAlternates) + 8.0) - } + if numAlternates > 0 { + alternatesViewWidth = CGFloat(width * numAlternates + (3.0 * numAlternates) + 8.0) + } - alternatesViewY = frame.origin.y - key.frame.height * 1.135 - alternatesBtnHeight = key.frame.height * 0.9 - alternatesKeyView = UIView( - frame: CGRect( - x: alternatesViewX, - y: alternatesViewY, - width: alternatesViewWidth, - height: key.frame.height * 1.2 + alternatesViewY = frame.origin.y - key.frame.height * 1.135 + alternatesBtnHeight = key.frame.height * 0.9 + alternatesKeyView = UIView( + frame: CGRect( + x: alternatesViewX, + y: alternatesViewY, + width: alternatesViewWidth, + height: key.frame.height * 1.2 + ) ) - ) - alternatesKeyView.tag = 1001 - key.backgroundColor = keyColor + alternatesKeyView.tag = 1001 + key.backgroundColor = keyColor + } } diff --git a/Keyboards/KeyboardsBase/KeyAnimation.swift b/Keyboards/KeyboardsBase/KeyAnimation.swift index a9ec6bf1..41413578 100644 --- a/Keyboards/KeyboardsBase/KeyAnimation.swift +++ b/Keyboards/KeyboardsBase/KeyAnimation.swift @@ -270,53 +270,54 @@ func centerKeyPopPath( /// - displayChar: the character to display on the pop up. func getKeyPopPath(key: UIButton, layer: CAShapeLayer, char: String, displayChar: String) { // Get the frame in respect to the superview. - let frame = (key.superview?.convert(key.frame, to: nil))! - var labelVertPosition = frame.origin.y - key.frame.height / 1.75 - // non-capital characters should be higher for portrait phone views. - if displayChar == char, DeviceType.isPhone, !isLandscapeView, - !["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].contains(char) - { - labelVertPosition = frame.origin.y - key.frame.height / 1.6 - } else if DeviceType.isPad, - isLandscapeView - { - labelVertPosition = frame.origin.y - key.frame.height / 2 - } - - if centralKeyChars.contains(char) { - layer.path = centerKeyPopPath( - startX: frame.origin.x, startY: frame.origin.y, - keyWidth: key.frame.width, keyHeight: key.frame.height, char: char - ).cgPath - keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.5, y: labelVertPosition) - keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.5, y: labelVertPosition) - } else if leftKeyChars.contains(char) { - layer.path = leftKeyPopPath( - startX: frame.origin.x, startY: frame.origin.y, - keyWidth: key.frame.width, keyHeight: key.frame.height, char: char - ).cgPath - keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.85, y: labelVertPosition) - keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.85, y: labelVertPosition) - if DeviceType.isPad || (DeviceType.isPhone && isLandscapeView) { - keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.65, y: labelVertPosition) - keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.65, y: labelVertPosition) + if let frame = key.superview?.convert(key.frame, to: nil) { + var labelVertPosition = frame.origin.y - key.frame.height / 1.75 + // non-capital characters should be higher for portrait phone views. + if displayChar == char, DeviceType.isPhone, !isLandscapeView, + !["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].contains(char) + { + labelVertPosition = frame.origin.y - key.frame.height / 1.6 + } else if DeviceType.isPad, + isLandscapeView + { + labelVertPosition = frame.origin.y - key.frame.height / 2 } - } else if rightKeyChars.contains(char) { - layer.path = rightKeyPopPath( - startX: frame.origin.x, startY: frame.origin.y, - keyWidth: key.frame.width, keyHeight: key.frame.height, char: char - ).cgPath - keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.15, y: labelVertPosition) - keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.15, y: labelVertPosition) - if DeviceType.isPad || (DeviceType.isPhone && isLandscapeView) { - keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.35, y: labelVertPosition) - keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.35, y: labelVertPosition) + + if centralKeyChars.contains(char) { + layer.path = centerKeyPopPath( + startX: frame.origin.x, startY: frame.origin.y, + keyWidth: key.frame.width, keyHeight: key.frame.height, char: char + ).cgPath + keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.5, y: labelVertPosition) + keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.5, y: labelVertPosition) + } else if leftKeyChars.contains(char) { + layer.path = leftKeyPopPath( + startX: frame.origin.x, startY: frame.origin.y, + keyWidth: key.frame.width, keyHeight: key.frame.height, char: char + ).cgPath + keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.85, y: labelVertPosition) + keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.85, y: labelVertPosition) + if DeviceType.isPad || (DeviceType.isPhone && isLandscapeView) { + keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.65, y: labelVertPosition) + keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.65, y: labelVertPosition) + } + } else if rightKeyChars.contains(char) { + layer.path = rightKeyPopPath( + startX: frame.origin.x, startY: frame.origin.y, + keyWidth: key.frame.width, keyHeight: key.frame.height, char: char + ).cgPath + keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.15, y: labelVertPosition) + keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.15, y: labelVertPosition) + if DeviceType.isPad || (DeviceType.isPhone && isLandscapeView) { + keyPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.35, y: labelVertPosition) + keyHoldPopChar.center = CGPoint(x: frame.origin.x + key.frame.width * 0.35, y: labelVertPosition) + } } - } - layer.strokeColor = keyShadowColor - layer.fillColor = keyColor.cgColor - layer.lineWidth = 1.0 + layer.strokeColor = keyShadowColor + layer.fillColor = keyColor.cgColor + layer.lineWidth = 1.0 + } } /// Sizes the character displayed on a key pop for iPhones. diff --git a/Keyboards/KeyboardsBase/KeyboardViewController.swift b/Keyboards/KeyboardsBase/KeyboardViewController.swift index d0d04547..72dad3fb 100644 --- a/Keyboards/KeyboardsBase/KeyboardViewController.swift +++ b/Keyboards/KeyboardsBase/KeyboardViewController.swift @@ -1855,12 +1855,6 @@ class KeyboardViewController: UIInputViewController { } } - if userDefaults.bool(forKey: "svAccentCharacters") { - disableAccentCharacters = true - } else { - disableAccentCharacters = false - } - // Actions to be done only on initial loads. if isFirstKeyboardLoad { shiftButtonState = .shift diff --git a/Keyboards/KeyboardsBase/ScribeFunctionality/CommandBar.swift b/Keyboards/KeyboardsBase/ScribeFunctionality/CommandBar.swift index 4e20acb3..bc6faa8f 100644 --- a/Keyboards/KeyboardsBase/ScribeFunctionality/CommandBar.swift +++ b/Keyboards/KeyboardsBase/ScribeFunctionality/CommandBar.swift @@ -47,7 +47,12 @@ class CommandBar: UILabel { /// Allows the class to be accessed from Keyboard.xib. class func instanceFromNib() -> UIView { - return UINib(nibName: "Keyboard", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView + let nibContents = UINib(nibName: "Keyboard", bundle: nil).instantiate(withOwner: nil, options: nil) + if let view = nibContents.first as? UIView { + return view + } else { + fatalError("Failed to instantiate view from nib.") + } } var shadow: UIButton! diff --git a/Keyboards/KeyboardsBase/ScribeFunctionality/Plural.swift b/Keyboards/KeyboardsBase/ScribeFunctionality/Plural.swift index 0265759f..ef7b6e13 100644 --- a/Keyboards/KeyboardsBase/ScribeFunctionality/Plural.swift +++ b/Keyboards/KeyboardsBase/ScribeFunctionality/Plural.swift @@ -50,7 +50,7 @@ func queryPlural(commandBar: UILabel) { let args = [noun] let outputCols = ["plural"] wordToReturn = queryDBRow(query: query, outputCols: outputCols, args: args)[0] - + guard !wordToReturn.isEmpty else { commandState = .invalid return diff --git a/Keyboards/KeyboardsBase/ScribeFunctionality/ScribeKey.swift b/Keyboards/KeyboardsBase/ScribeFunctionality/ScribeKey.swift index dffad4d4..b50a4c20 100644 --- a/Keyboards/KeyboardsBase/ScribeFunctionality/ScribeKey.swift +++ b/Keyboards/KeyboardsBase/ScribeFunctionality/ScribeKey.swift @@ -31,7 +31,10 @@ class ScribeKey: UIButton { /// Allows the class to be accessed from Keyboard.xib. class func instanceFromNib() -> UIView { - return UINib(nibName: "Keyboard", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView + guard let nibContents = UINib(nibName: "Keyboard", bundle: nil).instantiate(withOwner: nil, options: nil).first as? UIView else { + fatalError("Failed to instantiate view from nib.") + } + return nibContents } /// Converts the Scribe key to an escape key to return to the base keyboard view. diff --git a/Scribe/AboutTab/AboutViewController.swift b/Scribe/AboutTab/AboutViewController.swift index d218b90f..f8894a17 100644 --- a/Scribe/AboutTab/AboutViewController.swift +++ b/Scribe/AboutTab/AboutViewController.swift @@ -17,12 +17,11 @@ * along with this program. If not, see . */ -import UIKit import MessageUI import StoreKit +import UIKit final class AboutViewController: BaseTableViewController { - override var dataSet: [ParentTableCellModel] { AboutTableData.aboutTableData } @@ -39,10 +38,10 @@ final class AboutViewController: BaseTableViewController { // MARK: UITableViewDataSource extension AboutViewController { - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: AboutTableViewCell.reuseIdentifier, for: indexPath) as! AboutTableViewCell - + guard let cell = tableView.dequeueReusableCell(withIdentifier: AboutTableViewCell.reuseIdentifier, for: indexPath) as? AboutTableViewCell else { + fatalError("Failed to dequeue AboutTableViewCell.") + } cell.configureCell(for: dataSet[indexPath.section].section[indexPath.row]) return cell @@ -52,7 +51,6 @@ extension AboutViewController { // MARK: UITableViewDelegate extension AboutViewController { - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let tableSection = dataSet[indexPath.section] let section = tableSection.section[indexPath.row] @@ -100,11 +98,10 @@ extension AboutViewController { case .appLang: break case .none: break - case .specificLang(_): break + case .specificLang: break case .externalLink: break } - if let selectedIndexPath = tableView.indexPathForSelectedRow { tableView.deselectRow(at: selectedIndexPath, animated: false) } @@ -159,7 +156,7 @@ extension AboutViewController { guard let encodedURLString = encodedString, let url = URL(string: encodedURLString) else { return } let shareSheetVC = UIActivityViewController(activityItems: [url], applicationActivities: nil) - + present(shareSheetVC, animated: true, completion: nil) } } @@ -167,7 +164,6 @@ extension AboutViewController { // MARK: - MFMailComposeViewControllerDelegate extension AboutViewController: MFMailComposeViewControllerDelegate { - func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith _: MFMailComposeResult, error _: Error?) { controller.dismiss(animated: true, completion: nil) } diff --git a/Scribe/AppExtensions.swift b/Scribe/AppExtensions.swift index a62ed855..7c683ea1 100644 --- a/Scribe/AppExtensions.swift +++ b/Scribe/AppExtensions.swift @@ -31,20 +31,29 @@ extension UIImage { if let image = UIImage(named: imageString) { return image } else { - return UIImage(systemName: imageString) ?? UIImage(systemName: "info.circle")! + if let image = UIImage(systemName: imageString) { + return image + } else { + guard let infoCircleSymbol = UIImage(systemName: "info.circle") else { + fatalError("Failed to create info circle symbol image.") + } + return infoCircleSymbol + } } } } extension UIView { var parentViewController: UIViewController? { - var parentResponder: UIResponder? = self - while parentResponder != nil { - parentResponder = parentResponder!.next - if parentResponder is UIViewController { - return parentResponder as? UIViewController + var currentResponder: UIResponder? = self + + while let responder = currentResponder { + if let viewController = responder as? UIViewController { + return viewController } + currentResponder = responder.next } + return nil } } diff --git a/Scribe/AppUISymbols.swift b/Scribe/AppUISymbols.swift index f92ec0b9..2a99f01d 100644 --- a/Scribe/AppUISymbols.swift +++ b/Scribe/AppUISymbols.swift @@ -32,7 +32,9 @@ func getSettingsSymbol(fontSize: CGFloat) -> UIImage { settingsSymbolConfig = UIImage.SymbolConfiguration(pointSize: fontSize * 0.15, weight: .medium, scale: .medium) } } - let settingsSymbol = UIImage(systemName: "gearshape", withConfiguration: settingsSymbolConfig)! + guard let settingsSymbol = UIImage(systemName: "gearshape", withConfiguration: settingsSymbolConfig) else { + fatalError("Failed to create settings symbol image.") + } return settingsSymbol } @@ -50,7 +52,9 @@ func getPrivacySymbol(fontSize: CGFloat) -> UIImage { privacySymbolConfig = UIImage.SymbolConfiguration(pointSize: fontSize * 0.2, weight: .medium, scale: .medium) } } - let privacySymbol = UIImage(systemName: "lock.shield", withConfiguration: privacySymbolConfig)! + guard let privacySymbol = UIImage(systemName: "lock.shield", withConfiguration: privacySymbolConfig) else { + fatalError("Failed to create privacy symbol image.") + } return privacySymbol } diff --git a/Scribe/Components/TableViewTemplateViewController.swift b/Scribe/Components/TableViewTemplateViewController.swift index 765e87ed..92b42d2b 100644 --- a/Scribe/Components/TableViewTemplateViewController.swift +++ b/Scribe/Components/TableViewTemplateViewController.swift @@ -20,7 +20,6 @@ import UIKit final class TableViewTemplateViewController: BaseTableViewController { - // MARK: - Properties override var dataSet: [ParentTableCellModel] { @@ -63,10 +62,10 @@ final class TableViewTemplateViewController: BaseTableViewController { // MARK: - UITableViewDataSource extension TableViewTemplateViewController { - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: InfoChildTableViewCell.reuseIdentifier, for: indexPath) as! InfoChildTableViewCell - + guard let cell = tableView.dequeueReusableCell(withIdentifier: InfoChildTableViewCell.reuseIdentifier, for: indexPath) as? InfoChildTableViewCell else { + fatalError("Failed to dequeue InfoChildTableViewCell.") + } cell.parentSection = parentSection cell.configureCell(for: tableData[indexPath.section].section[indexPath.row]) diff --git a/Scribe/InstallationTab/InstallationVC.swift b/Scribe/InstallationTab/InstallationVC.swift index 7e5bbd69..189f001a 100644 --- a/Scribe/InstallationTab/InstallationVC.swift +++ b/Scribe/InstallationTab/InstallationVC.swift @@ -166,8 +166,12 @@ class InstallationVC: UIViewController { // Set link attributes for all textViews. for textView in allTextViews { + guard let linkBlueColor = UIColor(named: "linkBlue") else { + fatalError("Failed to load linkBlue color.") + } + textView.linkTextAttributes = [ - NSAttributedString.Key.foregroundColor: UIColor(named: "linkBlue")!, + NSAttributedString.Key.foregroundColor: linkBlueColor, NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue, ] } @@ -184,7 +188,6 @@ class InstallationVC: UIViewController { // Enable installation directions and GitHub notice elements. settingsBtn.isUserInteractionEnabled = true appTextBackground.backgroundColor = UIColor(named: "commandBar") - // Set the texts for the fields. switch Locale.userSystemLanguage { @@ -221,7 +224,10 @@ class InstallationVC: UIViewController { /// Function to open the settings app that is targeted by settingsBtn. @objc func openSettingsApp() { - UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!) + guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { + fatalError("Failed to create settings URL.") + } + UIApplication.shared.open(settingsURL) } /// Function to change the key coloration given a touch down. diff --git a/Scribe/SettingsTab/SettingsTableData.swift b/Scribe/SettingsTab/SettingsTableData.swift index c3291a97..a0159dc4 100644 --- a/Scribe/SettingsTab/SettingsTableData.swift +++ b/Scribe/SettingsTab/SettingsTableData.swift @@ -19,8 +19,7 @@ import Foundation -struct SettingsTableData { - +enum SettingsTableData { static let settingsTableData: [ParentTableCellModel] = [ ParentTableCellModel( headingTitle: NSLocalizedString("settings.appSettings", comment: "The title of the app settings section"), @@ -69,7 +68,7 @@ struct SettingsTableData { ), ], hasDynamicData: nil - ) + ), ] static func getInstalledKeyboardsSections() -> [Section] { @@ -90,9 +89,12 @@ struct SettingsTableData { var sections = [Section]() for language in installedKeyboards { + guard let abbreviation = languagesAbbrDict[language] else { + fatalError("Abbreviation not found for language: \(language)") + } let newSection = Section( sectionTitle: language, - sectionState: .specificLang(languagesAbbrDict[language]!) + sectionState: .specificLang(abbreviation) ) sections.append(newSection) diff --git a/Scribe/SettingsTab/SettingsViewController.swift b/Scribe/SettingsTab/SettingsViewController.swift index eb1cf445..d272b258 100644 --- a/Scribe/SettingsTab/SettingsViewController.swift +++ b/Scribe/SettingsTab/SettingsViewController.swift @@ -47,7 +47,6 @@ final class SettingsViewController: UIViewController { parentTable.backgroundColor = .clear parentTable.sectionHeaderHeight = sectionHeaderHeight parentTable.separatorInset = separatorInset - setFooterButtonView() @@ -82,7 +81,6 @@ final class SettingsViewController: UIViewController { parentTable.tableFooterView?.isHidden = false } - footerButton.setTitle("Install keyboard", for: .normal) footerButton.titleLabel?.font = .systemFont(ofSize: fontSize * 1.5, weight: .bold) @@ -104,7 +102,9 @@ extension SettingsViewController: UITableViewDataSource { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: InfoChildTableViewCell.reuseIdentifier, for: indexPath) as! InfoChildTableViewCell + guard let cell = tableView.dequeueReusableCell(withIdentifier: InfoChildTableViewCell.reuseIdentifier, for: indexPath) as? InfoChildTableViewCell else { + fatalError("Failed to dequeue InfoChildTableViewCell") + } let section = tableData[indexPath.section] let setting = section.section[indexPath.row] @@ -127,7 +127,7 @@ extension SettingsViewController: UITableViewDelegate { if let viewController = storyboard?.instantiateViewController(identifier: "TableViewTemplateViewController") as? TableViewTemplateViewController { // Copy base settings var data = SettingsTableData.languageSettingsData - + // Check if the device is an iPad, and if so don't show the option to put a period and comma on the ABC characters. let periodCommaOptionIndex = SettingsTableData.languageSettingsData[0].section.firstIndex(where: { s in s.sectionTitle.elementsEqual("Period and comma on ABC")