4

I am having a difficult time setting an image of a UIButton. I have checked other posts on how to do this, and it seems straightforward enough (but then, here I am).

In my program, the image that the button displays depends on trip.weather. I am using a switch to set the image before trying to set the button's image. However, while debugging, the console displays the following:

'2015-05-03 13:40:31.117 PackPlanner[581:4465] < UIImage: 0x7fd2a843fac0>, {600, 300} fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)'

class TripOverviewViewController: UITableViewController {


@IBOutlet var highTempLabel: UILabel!
@IBOutlet var lowTempLabel: UILabel!
@IBOutlet var weatherLabel: UILabel!
@IBOutlet var locationLabel: UILabel!
@IBOutlet var dateLabel: UILabel!
@IBOutlet var numOfPeopleLabel: UILabel!
@IBOutlet var sunriseLabel: UILabel!
@IBOutlet var sunsetLabel: UILabel!
@IBOutlet weak var weatherButtonImage: UIButton!

@IBAction func weatherButton(sender: UIButton) {
}


var tripItem: AnyObject? {
    didSet {
        // Update the view.
        self.configureView()
    }
}

func configureView() {
    // Update the user interface for the trip detail.
            if let trip: Trip = self.tripItem as? Trip{

                if var label = self.locationLabel {
                    label.text = trip.location
                }
                if var label = self.numOfPeopleLabel {
                    label.text = trip.numOfPeople.stringValue
                }
                if var label = self.dateLabel {
                    var formattedDate = NSDateFormatter.localizedStringFromDate(trip.startDate, dateStyle: .LongStyle, timeStyle: .NoStyle)
                    label.text = formattedDate
                }
                if var label = self.weatherLabel {
                    label.text = trip.weather
                }

                var theImage = UIImage(named: "Sunny") as UIImage!
                switch trip.weather {
                    case "Partly Cloudy":
                        theImage = UIImage(named:"PartlyCloudy")
                    case "Light Snow":
                        theImage = UIImage(named:"LightSnow")
                    case "Rainy":
                        theImage = UIImage(named:"Rainy")
                    default:
                        theImage = UIImage(named:"Sunny")

                }
                NSLog(" \(theImage.description)") //for debugging
                self.weatherButtonImage.setImage(theImage, forState: .Normal)

    }
}


override func viewDidLoad() {
    super.viewDidLoad()
    self.configureView()


}
turbs
  • 85
  • 8
  • Which line does it stop on? Which object is nil? – Paulw11 May 03 '15 at 21:54
  • Here: self.weatherButtonImage.setImage(theImage, forState: .Normal). The UIImage itself seems to be fine. I just edited the question to show the output of the NSLog that is right before the error. – turbs May 03 '15 at 21:57
  • So either `theImage` is nil or `weatherButtonImage` is nil. Which is it? Have you double checked your image names? – Paulw11 May 03 '15 at 22:01
  • weatherButtonImage is nil. I have checked the image names so many times, it makes me crazy! :( – turbs May 03 '15 at 22:03
  • Ok, so why is `weatherButtonImage` nil? - Did you connect the IBOutlet in Interface Builder? – Paulw11 May 03 '15 at 22:04
  • Yep. Used the drag n' drop method from storyboard to file. – turbs May 03 '15 at 22:07
  • Set a breakpoint in `viewDidLoad` and check if `weatherButtonImage` is nil there. Try removing the IBOutlet connection and re-creating it. The error message you are receiving is clear and you can see that your button is nil - you just need to work out why. – Paulw11 May 03 '15 at 22:08
  • You need to implicitly unwrap adding an exclamation "!" At the end UIImage(named: "yourImage")! – Leo Dabus May 03 '15 at 22:28
  • 1
    Cast as UIImage! Makes no sense – Leo Dabus May 03 '15 at 22:29

2 Answers2

2

Are you sure theImage exists and is not nil? UIImage may not be able to find that image named "Sunny". Another possibility is that self.weatherButtonImage is nil at that point (I see it's an outlet), so try setting it when the IB layout is complete at viewDidLayoutSubviews.

Schemetrical
  • 5,506
  • 2
  • 26
  • 43
1

Try this after NSLog(" (theImage.description)")

    if let tempButton = self.weatherButtonImage
    {
    tempButton.setImage(theImage, forState:.Normal)
    } else
    { NSLog("Button is nil")
    }

To determine if its your button that is nil.

If your button is nil, reconnect it in storyboard.

Garret
  • 1,137
  • 9
  • 17
  • Checkout this link for info on how to reconnect your IBOutlet http://stackoverflow.com/questions/24523086/xcode-interface-builder-correct-way-to-delete-rename-miswired-iboutlets-ib – Garret May 03 '15 at 22:10
  • Thank you. I just tried something like this, and the Button is definitely nil. I suspect I must have done something weird while in the storyboard file. I reconnected it. No luck. – turbs May 03 '15 at 22:11
  • You could have a bad link in there from a previous attempt. Go to your storyboard, at the top of your view controller, right click on the yellow circle with a square in it. If you see any connections with a yellow triangle, remove them, as they are bad links. I have to do this all the time. – Garret May 03 '15 at 22:15
  • 1
    I see you run configureView when tripItem is set. Is it possible to set a tripItem before the view is loaded? If so, that's bad news for your button. – Garret May 03 '15 at 22:17
  • I think you are onto something with your last comment. I moved the code for setting the button's image from configureView() to viewDidLoad(). Works! Thank you. – turbs May 03 '15 at 22:36
  • Maybe I am being greedy for info now, but can you explain why my original method was problematic? – turbs May 03 '15 at 22:37
  • 1
    ConfigureView should only determine the image and not place it on the button since configureView could be run before the view loads and the button is created... – Garret May 03 '15 at 22:39
  • Does that make sense? – Garret May 03 '15 at 22:41
  • Actually, yes. Seems simple enough. Thank you very much! – turbs May 03 '15 at 22:42