简体   繁体   中英

Swift-Keep getting “fatal error: unexpectedly found nil while unwrapping an Optional value”

I've only been working with Swift and Xcode 6 for a few weeks, but I'm already working on an idea I have for an app. The part of the app I'm trying to work on would go like this: 1) User has a grid of buttons, which each do something different when tapped 2) User can tap a gear button on the bottom right of the view and then will have a new view presented modally, a makeshift settings pane (labels and switches). If the switch by the label of the name of the button is off, than that button is hidden. 3) User hits a Save button (which currently has NOTHING to do with NSUserDefaults or anything to do with actually saving features once the app is closed, it's CURRENTLY really just a back button) and any switches which are turned off make their respective button outlets hidden.

However, the actual project runs like this: 1) Works perfectly 2) When I tap the gear, the settings pane appears, as planned. I can also slide switches all around, but when I tap the save button, the app crashes and I get "fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)" in the console.

Here's my code:

This is part of the first view controller with the buttons on it:

@IBAction func soundButton(sender: AnyObject) {
    var soundID: SystemSoundID = 0
    let soundFile: String = NSBundle.mainBundle().pathForResource("Sound", ofType: "wav")!
    let soundURL: NSURL = NSURL(fileURLWithPath: soundFile)!
    AudioServicesCreateSystemSoundID(soundURL, &soundID)
    AudioServicesPlaySystemSound(soundID)
}

Above is an action which plays a sound when a button is pushed.

Now here's the outlet for the button and one for the border for it:

 @IBOutlet var soundOutlet: UIButton!
 @IBOutlet var soundRingOutlet: UIImageView!

In the storyboard, I have a tab bar controller and two views (ViewController and ViewControllerTwo), to access the settings view (SettingsViewController) I made a button with an image of a gear on it in the lower right hand corner, which is connected to the settings pane by a modally presented segue. HERE'S PART OF THE CODE FOR THE SettingsViewController:

//The switch
@IBOutlet var soundSwitch: UISwitch!

HERE'S WHERE THE ISSUE IS:

@IBAction func saveButton(sender: AnyObject) { if soundSwitch.on{
    (presentedViewController as! ViewController).soundOutlet.hidden = true} else {(presentedViewController as! ViewController).soundOutlet.hidden = false
    dismissViewControllerAnimated(true, completion: nil)
    }

The issue is from the second instance of "presentedViewController" to "false" Very frustrating problem, I've been working on this for hours, swapped code around, researched this, but nothing seems to work. There is obviously something I'm missing, after all, this is just exchanging data between views.

UPDATE: I've changed the two "presentedViewController"s in my problem with "presentingViewController"s instead. I got this error message in the console: "Could not cast value of type 'Buttons.TabBarViewController' (0x10d590d90) to 'Buttons.ViewController' (0x10d590e10). (lldb)" "Buttons" would be the project name.

present ing ViewController is your tabBarViewController, while present ed ViewController is what you are expecting to be your ViewController that is being presented, but infact this variable is nil because at the point in time you clicked this button, the modal viewcontroller hasnt set the presentedViewController variable for some reason, so the variable is actually nil, and when you trying to go as! ViewController as! ViewController on a nil variable, you are trying to cast nil to something it cant be so you get the crash, you'll have to find some other way to get hold of your viewcontroller that will be presented

Red, most of this looks OK. Just a couple of tips.

  1. You don't have to duplicate your variable declarations.

    let soundURL : NSURL = NSURL(fileURLWithPath: soundFile)!

Swift will infer your type in this case by your assignment.

  1. As others have mentioned, use descriptive class names for your controllers. It will save you a lot of time when you're trying to figure out the purpose of the class. We've all been there 8>).

You will need to instantiate an instance of your controller that holds the soundOutlet property. Something like:

let dvc = YourControllerClass() 
dvc.soundOutlet.hidden = true
dvc.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
dvc.modalPresentationStyle = UIModalPresentationStyle.Popover
dvc.presentViewController(YourViewController, animated: true, completion: nil)

If you have not figured it out, post more of your implementation.

Good Luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM