有没有办法强制 Swift 中的 TextField 中的文本为非可选文本?
Is there a way to force the text in a TextField in Swift to be non-optional?
我正在制作一个应用程序,该应用程序从 alertController 中的文本字段获取输入,然后存储到 CoreData 中并最终显示在 tableView 中。
目前的计划是通过将 textField.text 组合在一起来创建一个字符串来创建 CSV,例如
let string CSV = textField.text + " ," + textField2.text + " ," + ...
但是,当我尝试这样做时,他们说我不能强制展开可选值。
我试着放一个“!”在 textField.text 等中,但它们仍然被视为可选值。文本字段在应用程序中使用时必须始终填写,但我找不到提供强制应用程序用户填写值的错误的方法。
这是我的 ViewController:
import UIKit
import CoreData
class ViewController: UITableViewController {
var alarmItems: [NSManagedObject] = []
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
navigationController?.navigationBar.barTintColor = UIColor(red: 21/255, green: 101/255, blue: 192/255, alpha: 1)
navigationController?.navigationBar.tintColor = .white
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add Alarm", style: .plain, target: self, action: #selector(addAlarmItem))
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "AlarmItems")
do {
alarmItems = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
//now to figure out how to add multiple text fields
@objc func addAlarmItem(_ sender: AnyObject) {
print("this works")
let alertController = UIAlertController(title: "Add New Item", message: "Please fill in the blanks", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default) { [unowned self] action in
guard let textField = alertController.textFields!.first, let itemToAdd = textField.text else { return }
//guard let textField2 = alertController.textFields?.first, let itemToAdd2 = textField2.text else { return } //tried this to get the input of a second textField
/*
one thing I tried:
let textField1 = alertController.textFields[0]
let textField1String = textField1.text!
let textField2 = alertController.textFields![1]
let textField2String = textField2.text
let itemToAdd = textField1String + textField2String
*/
//var textField1String = textField1.text
//let textField2 = alertController.textFields![1]
//var textField2String = textField2.text
self.save(itemToAdd)
//self.save(itemToAdd2)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
//alertController.addTextField(configurationHandler: nil)
alertController.addTextField { (textField) in
textField.placeholder = "First"
}
alertController.addTextField { (textField) in
textField.placeholder = "Second"
}
//let combinedString = UITextField[0] + " ," + UITextField[1]
alertController.addAction(saveAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func save(_ itemName: String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "AlarmItems", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(itemName, forKey: "alarmAttributes")
do {
try managedContext.save()
alarmItems.append(item)
} catch let err as NSError {
print("Failed to save an item", err)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return alarmItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let alarmItem = alarmItems[indexPath.row]
cell.textLabel?.text = alarmItem.value(forKeyPath: "alarmAttributes") as? String
return cell
}
}
您可以使用 compactMap 轻松地将可选数组转换为 non-optionals 数组。
let myStrings: [String] = alert.textfields!.compactMap { [=10=].text }
let myText = myStrings.joined(separator: ", ")
要了解有关 compactMap 的更多信息,请前往 https://developer.apple.com/documentation/swift/sequence/2950916-compactmap
您可以执行错误验证的方法之一是按下保存时,在单独的函数中对文本字段值进行空检查并显示错误警告框。
我认为您无法在初始文本字段警报控制器中显示某种错误。您必须单独验证文本,然后显示单独的警报错误警报框。
您可以使用字符串扩展以这种方式展开文本:
extension Optional where Wrapped == String{
func safe() -> String{
if self == nil{
return ""
}else{
return self.unsafelyUnwrapped
}
}
希望对您有所帮助。
我正在制作一个应用程序,该应用程序从 alertController 中的文本字段获取输入,然后存储到 CoreData 中并最终显示在 tableView 中。
目前的计划是通过将 textField.text 组合在一起来创建一个字符串来创建 CSV,例如
let string CSV = textField.text + " ," + textField2.text + " ," + ...
但是,当我尝试这样做时,他们说我不能强制展开可选值。
我试着放一个“!”在 textField.text 等中,但它们仍然被视为可选值。文本字段在应用程序中使用时必须始终填写,但我找不到提供强制应用程序用户填写值的错误的方法。
这是我的 ViewController:
import UIKit
import CoreData
class ViewController: UITableViewController {
var alarmItems: [NSManagedObject] = []
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
navigationController?.navigationBar.barTintColor = UIColor(red: 21/255, green: 101/255, blue: 192/255, alpha: 1)
navigationController?.navigationBar.tintColor = .white
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add Alarm", style: .plain, target: self, action: #selector(addAlarmItem))
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "AlarmItems")
do {
alarmItems = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
//now to figure out how to add multiple text fields
@objc func addAlarmItem(_ sender: AnyObject) {
print("this works")
let alertController = UIAlertController(title: "Add New Item", message: "Please fill in the blanks", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default) { [unowned self] action in
guard let textField = alertController.textFields!.first, let itemToAdd = textField.text else { return }
//guard let textField2 = alertController.textFields?.first, let itemToAdd2 = textField2.text else { return } //tried this to get the input of a second textField
/*
one thing I tried:
let textField1 = alertController.textFields[0]
let textField1String = textField1.text!
let textField2 = alertController.textFields![1]
let textField2String = textField2.text
let itemToAdd = textField1String + textField2String
*/
//var textField1String = textField1.text
//let textField2 = alertController.textFields![1]
//var textField2String = textField2.text
self.save(itemToAdd)
//self.save(itemToAdd2)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
//alertController.addTextField(configurationHandler: nil)
alertController.addTextField { (textField) in
textField.placeholder = "First"
}
alertController.addTextField { (textField) in
textField.placeholder = "Second"
}
//let combinedString = UITextField[0] + " ," + UITextField[1]
alertController.addAction(saveAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func save(_ itemName: String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "AlarmItems", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(itemName, forKey: "alarmAttributes")
do {
try managedContext.save()
alarmItems.append(item)
} catch let err as NSError {
print("Failed to save an item", err)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return alarmItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let alarmItem = alarmItems[indexPath.row]
cell.textLabel?.text = alarmItem.value(forKeyPath: "alarmAttributes") as? String
return cell
}
}
您可以使用 compactMap 轻松地将可选数组转换为 non-optionals 数组。
let myStrings: [String] = alert.textfields!.compactMap { [=10=].text }
let myText = myStrings.joined(separator: ", ")
要了解有关 compactMap 的更多信息,请前往 https://developer.apple.com/documentation/swift/sequence/2950916-compactmap
您可以执行错误验证的方法之一是按下保存时,在单独的函数中对文本字段值进行空检查并显示错误警告框。
我认为您无法在初始文本字段警报控制器中显示某种错误。您必须单独验证文本,然后显示单独的警报错误警报框。
您可以使用字符串扩展以这种方式展开文本:
extension Optional where Wrapped == String{
func safe() -> String{
if self == nil{
return ""
}else{
return self.unsafelyUnwrapped
}
}
希望对您有所帮助。