我一直在发现同样的错误,导致XCode
崩溃。我意识到在没有值的情况下搜索值时会发生这种情况。但是,每次尝试解决问题的尝试都会导致失败。
这是提示错误的代码行:
textFields[0].text = detail.valueForKey("moduleName") as? String
VC:
class DetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, UITextViewDelegate {
var tasks = [NSSet]() // sets list array for Task objects
var courseWork: CourseWork? {
didSet {
// Update the view.
// do it in different thread cause some things take time to load...
dispatch_async(dispatch_get_main_queue()) {
self.configureView()
}
}
}
func configureView() { // Update the user interface for the detail view
if let detail = self.courseWork { // if user clicks on a coursework/runs the app, then the UI is automatically updated:
self.title = detail.valueForKey("courseWorkName")!.description // set title of navigation controller
textFields[0].text = detail.valueForKey("moduleName") as? String //set UITtext field for module name - Optional ?
textFields[1].text = detail.valueForKey("markAwarded") as? String // set UIText field for mark awarded - Optional ?
if let level = detail.valueForKey("level")!.intValue { // setup slider for level and its label
levelSlider.value = Float(level)
levelLabel.text = "Level: \(level)"
}
if let value = detail.valueForKey("value")!.intValue { // setup slider for value and its label
slider.value = Float(value)
valueLabel.text = "Value: \(value)"
}
textView.text = detail.valueForKey("notes") as? String ?? "Enter Notes here..." //set UITtext field for task notes
if let date = detail.valueForKey("dueDate") as? NSDate {
datePicker.setDate(date, animated: true)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
reminderDatePicker.hidden = true
textView.layer.borderWidth = 1
textView.layer.borderColor = UIColor.blueColor().CGColor
tableView.delegate = self
tableView.dataSource = self
tableView.estimatedRowHeight = tableView.rowHeight // dimensions
tableView.rowHeight = UITableViewAutomaticDimension //hide blank cells in table view
let backgroundView = UIView(frame: CGRectZero) // instantiating the view without an initial value for its frame
tableView.tableFooterView = backgroundView // purpose is to automatically size the tableView depending on number of objects
let addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "addNewTask") // "+" button is set as a button that adds tasks - addNewTask function is run
self.navigationItem.rightBarButtonItem = addButton // sets position of addButton - at the right of the bar
setupUIElements() // runs function
// datePicker.addTarget(self, action: "datePickerValueChanged:", forControlEvents:.ValueChanged)
datePicker.addTarget(self, action: "datePickerValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
//datePicker.addTarget(self, action: Selector("dataPickerChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//create alert with text field and create new item with that name
func addNewTask() {
self.performSegueWithIdentifier("showTaskDetail", sender: nil)
}
// setting the delegate - start by checking the identifier of the segue, making sure we're preparing for the correct segue. We then ask the segue for its destination view controller - TaskDetailViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
if identifier == "showTaskDetail" {
if let controller = segue.destinationViewController as? TaskDetailViewController {
controller.courseWork = self.courseWork // pass course work because of context
if sender != nil { // some task is selected and sent to showDetail
controller.task = sender as? Task
}
}
}
}
}
//Table view for tasks
@IBOutlet weak var tableView: UITableView!
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1 // only 1 section for the Task table view
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count // the number of rows in table view is equal to the number of tasks
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("taskCell", forIndexPath: indexPath) as! TaskCustomCell // refers to outlet variable in TaskCustomCell class
if let tasks = self.courseWork!.tasks {
let allTasks = tasks.allObjects // add all Task objects to constant
let task = allTasks[indexPath.row]
if let name = task.valueForKey("taskName") as? String { // if name is entered for Task name
cell.taskNameLabel.text = name // place value in UI Label
}
}
return cell
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete { // enables the deleting of tasks
if let tasks = self.courseWork!.tasks {
let allTasks = tasks.allObjects // add all Task objects to constant
let task = allTasks[indexPath.row] as! Task
MasterViewController().deleteTask(task) // calls deleteTask function from Master View Controller
NSNotificationCenter.defaultCenter().postNotificationName("updateDetailTableValues", object: nil) // updates task changes
}
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//send task with the segue to destination so values can be edited
if let tasks = self.courseWork!.tasks {
let allTasks = tasks.allObjects // add all Task objects to constant
let task = allTasks[indexPath.row]
self.performSegueWithIdentifier("showTaskDetail", sender: task)
}
}
//setup textField delegates for purpose of opening a new View - TaskDetailViewController
func setupUIElements() {
//text fields
for textF in textFields {
textF.delegate = self
}
textView.delegate = self
}
//Text fields
@IBOutlet var textFields: [UITextField]!
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField == textFields[0] { // module name field
saveTHeCourseWork("moduleName", value: textFields[0].text!)
} else if textField == textFields[1] { // mark awarded
saveTHeCourseWork("markAwarded", value: textFields[1].text!)
}
return true
}
//text view - notes
@IBOutlet weak var textView: UITextView!
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" { // if I see new line, or click Enter, I save it to Core Data
saveTHeCourseWork("notes", value: textView.text) // selected value is saved as the value for "notes"
textView.resignFirstResponder() // dismiss the xcode keyboard
}
return true
}
错误是:
在解包可选值时意外发现nil