Reputation: 35
Click the image above for a brief view of my Segue. My app is a workout tracker. I have a class that makes the workout object with properties such as workout name, description, etc. I have another object that creates the workoutlist, so just an array of Workout objects.
I have a UITableView and a button above it that lets the user create a new workout and adds it to the workoutList array.
The crash happens whenever I click this "create new workout" which segues to a new view controller. I get this error
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var setStepper: UILabel!
@IBOutlet weak var repStepper: UILabel!
@IBOutlet weak var workoutName: UITextField!
@IBOutlet weak var workoutDescription: UITextField!
@IBOutlet weak var tableView: UITableView!
var workoutList = WorkoutList().listOfWorkouts
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func stepperCounter(_ sender: UIStepper) {
if sender.tag == 1 {
setStepper.text = "\(Int(sender.value))"
}
else if sender.tag == 2 {
repStepper.text = "\(Int(sender.value))"
}
}
@IBAction func addToWorkout(_ sender: Any) {
//I know this is terrible fixing later. Just for Testing right now
let newWorkout : Workout = Workout(Name: workoutName.text!, Description: workoutDescription.text!, Sets: Int(setStepper.text!)!, Reps: Int(repStepper.text!)!)
workoutList.append(newWorkout)
print(workoutList.count)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return workoutList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "Hello"
return cell
}
}
Upvotes: 0
Views: 184
Reputation:
I'd guess that tableView
outlet isn't wired up in your storyboard - and that property is an implicitly unwrapped optional. You're promising that it won't be nil.
Upvotes: 0
Reputation: 126
it looks like you are using the same ViewController for both Views in your storyboard. Which means, when you push to the "AddNewWorkoutController" the viewDidLoad expects a tableView - which is not there, because the storyboard didn't build any for this view.
You should create 2 VCS. One for the OverView with the "add new button" and the tableview and another one for actually creating it.
here is a full solution:
create 2 new swift files:
OverViewViewController.swift & NewWorkoutViewController.swift
I just separated your code into 2 VC's:
import UIKit
class OverViewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var workoutList = WorkoutList().listOfWorkouts
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return workoutList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "Hello"
return cell
}
}
and
import UIKit
class NewWorkoutViewController: UIViewController {
@IBOutlet weak var setStepper: UILabel!
@IBOutlet weak var repStepper: UILabel!
@IBOutlet weak var workoutName: UITextField!
@IBOutlet weak var workoutDescription: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func stepperCounter(_ sender: UIStepper) {
if sender.tag == 1 {
setStepper.text = "\(Int(sender.value))"
}
else if sender.tag == 2 {
repStepper.text = "\(Int(sender.value))"
}
}
@IBAction func addToWorkout(_ sender: Any) {
//I know this is terrible fixing later. Just for Testing right now
let newWorkout : Workout = Workout(Name: workoutName.text!, Description: workoutDescription.text!, Sets: Int(setStepper.text!)!, Reps: Int(repStepper.text!)!)
workoutList.append(newWorkout)
print(workoutList.count)
}
}
Now go into the Storyboard, select the controllers and assign the right classes:
After assigning go and connect your tableView to the tableView in the OverView and the 2 actions in your NewWorkout.
This will work.
Upvotes: 1