-1

First of all, I've checked all of the other questions on this fatal error, and mine is different from the others.

code with error

import Firebase

var tappedUserController = TappedUserController()

class TappedUserController: UIViewController {

    @IBOutlet weak var tappedName: UILabel!
    @IBOutlet weak var tappedSport: UILabel!
    @IBOutlet weak var tappedZip: UILabel!
    @IBOutlet weak var tappedPhone: UILabel!
    @IBOutlet weak var tappedEmail: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let peopleView = PeopleViewController()

        let number = myIndex
        print(number)

        let tappedRow = peopleView.people[number]

        print(tappedRow)

        let tappedUser = FirebaseFirestore.root.collection("users").document()


override public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    myIndex = indexPath.row

    print(myIndex)
    print(people[0])

    performSegue(withIdentifier: "toTappedUser", sender: self)
}

0 Person(name: "Test1", zip: "95111", sport: "Tennis", email: "test1@email.com") 0 Fatal error: Index out of range 2019-08-24 18:12:25.041506-0700 Sports Partner[29777:4579375] Fatal error: Index out of range (lldb)

I'm trying to make an app about users and sports. On the right side (or second section of the code), when using didSelectRowAt, it should have gone to make myIndex to the indexPath.row. So if I tapped the first row when running the app, it should let myIndex equal to 0.

When printing myIndex, it also outputs 0.

Now when I print people[0], which should be the same as people[myIndex], it outputs what I want it to output, the data for that specific row.

Then, using performSegue, it goes to the next View Controller with the class on the left side (or the first section of code). I tried to get another variable (number) to equal to myIndex, but it doesn't change the output.

Printing number, it outputs 0 again. But when I get the public class peopleView and the public array people to do peopleView.people[number], the error

Fatal error: Index out of range

occurs.

I am very confused as to why this is happening, because printing people[0] should be the same as printing people[myIndex]. Can someone explain why this is happening?

EDIT

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let TappedUserController = segue.destination as? TappedUserController,
        let index = tableView.indexPathForSelectedRow?.row
        else {
            return
    }
    tappedUserController.selectedPerson = people[myIndex]
}
Kampai
  • 22,848
  • 21
  • 95
  • 95
leon
  • 117
  • 2
  • 13
  • @Sweeper, There is an image attached to it. Is it not visible on your screen? – leon Aug 25 '19 at 01:31
  • 2
    Ah oops! I forgot to turn on my VPN. You should not post code as images anyway. Code is text and should be posted as such. – Sweeper Aug 25 '19 at 01:32
  • @Sweeper, Oh sorry, I'll edit it now. – leon Aug 25 '19 at 01:33
  • In viewDidLoad you set `number = myIndex` but `myIndex` doesn’t seem to be defined at that point. However, I would expect that to show a compiler error. – Chris Aug 25 '19 at 01:33
  • Maybe try using [an extension such as this](https://stackoverflow.com/a/37225027/499581), that way you can catch the error without crashing and burning. – l'L'l Aug 25 '19 at 01:38
  • It seems like you are passing the array to the next VC wrongly. You should not do `let peopleView = ...`. Why are you passing the whole VC in the first place? You just need to pass `people[myIndex]` to the next view controller. There are a lot of resources online about passing data between view controllers, such as [this](https://matteomanferdini.com/how-ios-view-controllers-communicate-with-each-other/). – Sweeper Aug 25 '19 at 01:38
  • @Sweeper, I just tried only making ```people[myIndex]``` public, but this: ```Cannot assign value of type 'Person' to type 'String'```. Person is a struct with name, zip, sport, and email, and I did ```var people = [Person]()``` in the class. – leon Aug 25 '19 at 01:46
  • Making things public is not the right way to pass data to the next VC. Did you read the linked post? There are lots of posts on Stack Overflow as well. – Sweeper Aug 25 '19 at 01:48
  • @Sweeper, I used the link you sent and tried it (see edit), but this happens: ```Instance member 'selectedPerson' cannot be used on type 'tappedUserController'``` – leon Aug 25 '19 at 02:03
  • @l'L'l, I tried the extension, but the fatal error still shows. ```Index out of range```. – leon Aug 25 '19 at 02:15

1 Answers1

2

This is a very common mistake. The problem is the line let peopleView = PeopleViewController().

It returns a brand new instance of the controller which is not the instance in the storyboard. You need the real reference to the controller via segue or instantiation from the storyboard.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Hi, thank you. I just looked at how to reference scenes and found the solution here: https://stackoverflow.com/questions/48927609/referring-to-my-view-controller-in-another-class-scene-swift-all-variables-t. – leon Aug 30 '19 at 23:59