在展开可选值 uitextfield 时意外发现 nil
Posted
技术标签:
【中文标题】在展开可选值 uitextfield 时意外发现 nil【英文标题】:Unexpectedly found nil while unwrapping an optional value uitextfield 【发布时间】:2016-07-30 15:23:41 【问题描述】:我知道这里有很多意想不到的 nil 值问题,但我尝试了其他方法,但它们对我不起作用。底部的函数是从另一个视图控制器上的按钮调用的。基本上问题是此代码按预期工作,表单元素将 DatePicker 作为输入视图,并在值更改时更新 startDatePickerField.text,所以我知道 startDatePickerField.text 不为空,因为它显示在屏幕。但是,当从另一个包含我们正在使用的视图控制器调用 testForValidity() 函数时,我得到“在展开选项值错误时意外发现 nil”。所有的插座都连接正确,所以我知道不是这样。
class popoverTableViewController: UITableViewController, UIPickerViewDelegate, UIPickerViewDataSource
@IBOutlet var startDatePickerField: UITextField!
override func viewDidLoad()
let startDatePicker:UIDatePicker = UIDatePicker()
startDatePicker.datePickerMode = UIDatePickerMode.dateAndTime
startDatePickerField.inputView = startDatePicker
startDatePicker.minuteInterval = 5
startDatePicker.addTarget(self, action: #selector(popoverTableViewController.startDatePickerValueChanged(_:)), for: UIControlEvents.valueChanged)
@IBAction func startDateDidBegin(_ sender: AnyObject)
func startDatePickerValueChanged(_ sender: UIDatePicker)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = DateFormatter.Style.long
dateFormatter.timeStyle = DateFormatter.Style.short
startDatePickerField.text = dateFormatter.string(from: sender.date)
finishDateTime = sender.date
以及出错的函数:
func testForValidity()
print(startDatePickerField.text)
【问题讨论】:
testForValidity() 在哪里?在 popoverTableViewController 中?你怎么称呼它? testForValidity() 在 popoverTableViewController 是的,这是按下按钮后另一个类的简单调用。我已经意识到这个方法调用了我的 popoverTableViewController 的一个新实例,这就是我收到错误的原因。我认为修复与 NSNotificationCentre 有关,但我不确定如何实现它。 【参考方案1】:问题:
您正试图通过实例方法从另一个类访问 IBOutlet 属性。 nil 值背后的原因是 IBOutlets 在加载 nib 时被初始化。因此,当您在另一个视图控制器中时,您无法访问 Outlet 变量,否则您将始终得到 nil。
解决方案:
如果我假设正确,您想在视图控制器中包含一个值后使用一个值。
最好的方法是遵循“设计模式”。即,您必须将所需的值存储在模型类中并通过模型类实例访问该值。
Apple 有非常好的文档。请通过。 https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson6.html#//apple_ref/doc/uid/TP40015214-CH20-SW1
Swift 中的示例代码:
class TextFieldViewController: UIViewController, UITextFieldDelegate
@IBOutlet weak var outputLabel : UILabel!
@IBOutlet weak var textField : UITextField!
override func viewDidLoad() super.viewDidLoad(); setupTextField()
func testValidity() -> (textFieldValue: UITextField?, modelValue: String?)
return (textField, TextFieldModel.sharedModel.textFieldData)
//MARK: - Text Field Delegates
func textFieldShouldReturn(textField: UITextField) -> Bool
textField.resignFirstResponder()
outputLabel.text = textField.text
TextFieldModel.sharedModel.textFieldData = textField.text
return true
class TextFieldModel
static let sharedModel = TextFieldModel()
var textFieldData: String?
class DemoController: UIViewController
@IBOutlet weak var textFieldOutput: UILabel!
@IBOutlet weak var modelOutput: UILabel!
override func viewDidLoad() super.viewDidLoad(); testValues()
func testValues()
let tvc = TextFieldViewController()
textFieldOutput.text = "Value of Text field is " + (tvc.testValidity().textFieldValue?.text ?? "nil")
modelOutput.text = "Value accessed from Model Class is \(tvc.testValidity().modelValue)"
extension TextFieldViewController
func setupTextField()
textField.placeholder = ""
textField.delegate = self
textField.becomeFirstResponder()
textField.keyboardType = UIKeyboardType.Default
textField.returnKeyType = UIReturnKeyType.Done
输出:
【讨论】:
非常感谢您花时间回答,很有魅力! 不客气。很高兴我可以帮助您解决问题。【参考方案2】:在顶部添加UITextFieldDelegate
,使其变为:
class popoverTableViewController: UITableViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate
然后在viewDidLoad()
中添加这一行:
self.startDatePickerField.delegate = self
【讨论】:
以上是关于在展开可选值 uitextfield 时意外发现 nil的主要内容,如果未能解决你的问题,请参考以下文章
prepareForSegue 出错“”在展开可选值时意外发现 nil“”