Search code examples
arraysswiftstructviewcontroller

How to determine, and pull the correct Data from a structures with Arrays in swift


I have two table views that get populated from data that are pulled from Arrays according to the cell chosen.I have introduced structures, initially just with arrays of Strings and I am trying to pull the right data and populate the right fields with them.So I have this Struct:

  struct DetailView {
    var detailTitle : String
    
    //var equipmentImage = [UIImageView?]()
    var serN : String
    var dc : String //deck Code
    var an : String  //area name
    var sn : String   //Space number
    var manuf : String
    var qty : String
    
    init(detailTitle:String,dc:String,serN:String,an:String,sn:String,manuf:String,qty:String){
        self.detailTitle = detailTitle
        self.dc = dc
        self.an = an
        self.serN = serN
        self.sn = sn
        self.manuf = manuf
        self.qty = qty
//
    }
}

I have this array:

    //we are adding elements on the detailView structure

    var thirdArray : [DetailView]= []

I populate it:

    thirdArray = thirdArray = [[
                    DetailView(detailTitle: "A", dc: "", serN: "Info required", an: "Area Name required", sn: "Space Number Required", manuf: "APC", qty: "2")],
                    
                    [DetailView(detailTitle: "B", dc: "", serN: "Info required", an: "Area Name required", sn: "Space Number Required", manuf: "Apple", qty: "12"),
                    DetailView(detailTitle: "D", dc: "", serN: "Info required", an: "Area Name required", sn: "Space Number Required", manuf: "Apple", qty: "7"),
                    DetailView(detailTitle: "E", dc: "", serN: "Info required", an: "Area Name required", sn: "Space Number Required", manuf: "Apple", qty: "1")],
                    
                    
                    [DetailView(detailTitle: "F", dc: "", serN: "Info required", an: "Area Name required", sn: "Space Number Required", manuf: "Autonomic", qty: "1")]]

Then I perform a segue where I populate them:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
            let row = self.tableView?.indexPathForSelectedRow?.row ?? 0
            let destViewController = segue.destination as! SecondTableViewController
           var detailArray : [DetailView]
           detailArray = thirdArray
destViewController.detailVcArray = detailArray


}

on my second table view I have:

    var detailVcArray : [DetailView] = []


     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
             let destViewController = segue.destination as! DetailsViewController
             let row = self.tableView?.indexPathForSelectedRow?.row ?? 0
           


    var lastArray : [DetailView]
    lastArray = detailVcArray
    
    
    destViewController.displayDetail = lastArray[row]
         //here I get this error "Thread 1: Fatal error: Index out of range"   
        }

Lastly on my DetailsViewController I want to populate the dc textField with the dc data from my struct and the textView with the detailTitle etc ..But the app crashes.

      var displayDetail : DetailView?
        @IBOutlet weak var textView: UITextView!
        @IBOutlet weak var serN: UITextField!
        @IBOutlet weak var dc: UITextField!
        @IBOutlet weak var an: UITextField!
        @IBOutlet weak var sn: UITextField!
        @IBOutlet weak var manuf: UITextField!
        @IBOutlet weak var qty: UITextField!
        
            
         override func viewDidLoad() {
                super.viewDidLoad()
    
    textView.text = displayDetail?.detailTitle
        dc.text = displayDetail?.dc
        serN.text = displayDetail?.serN
        an.text = displayDetail?.an
        sn.text = displayDetail?.sn
        manuf.text = displayDetail?.manuf
        qty.text = displayDetail?.qty
         updateTextView()
                }

I get this error "Thread 1: Fatal error: Index out of range" and the app crashes when I choose a cell from my last TV and trying to present the data on my last VC.


Solution

  • I suggest redesigning your data model around the thing you need to display. In the end, you want 2 strings, so create that structure.

    struct Detail {
        var detailTitle: String
        var dc: String
    }
    

    You want to organize them as an array of arrays to match your two tables.

    let detailArray = [[Detail(detailTitle: "A", dc: "BO")],
        [Detail(detailTitle: "B", dc: "Apple"), Detail(detailTitle: "C", dc: "Apple"), Detail(detailTitle: "D", dc: "Apple")],
        [Detail(detailTitle: "A", dc: "BD")]
        //  ...
    ]
    

    Your segue picks the correct array and passes it to the second table's data source, which is...

    var detailVcArray: [Detail]
    

    And the last controller receives what it needs as...

    var displayDetail: Detail
    

    At that point you can use the values.

        textView.text = displayDetail.detailTitle
        dc.text = displayDetail.dc