6 Replies
      Latest reply on May 23, 2020 12:31 AM by Claude31
      BBExploration Level 1 Level 1 (0 points)

        I am new to Xcode macOS and Swift.  I searched far and wide to find

        a simple example for getting data values from a tableView.

        I figured out a simple example and am posting it here in hopes that

        it will help others.

         

        The trick is getting the indexes from the table on screen and

        then referencing your data source that is currently loaded in memory

        using the indexes from the table.

         

        The actual code is less than ten lines.  Explaining it is an entire page.

         

        This does use an extension which is a Swift file whose

        wrapped extension name is the same as your primary ViewController.

         

        The name of the extension files by convention is the name of

        the ViewController you are extending with an added plus sign '+' and

        finally the name of what this code page does or what this code page is.

         

        In this case it would be something like

        MainViewController+SimplePrintTableValuesExample

        But it is not mandatory.  You could call it 'beachBall. if you like.

         

        What is mandatory is the extension inside the code.

         

        My primary code page ViewController name is "MainViewController"

        That is why this code is wrapped in the line beginning

         

        extension MainViewController {     // -- Mandatory if your main view controller name is 'MainViewController'

         

        The rest of code is then wrapped in a single function - This is also mandatory

        I am extending the function tableViewSelectionDidChange.

        Xcode populated the rest of that line.

         

        The output is in the console (debug area) at the bottom of your

        Xcode screen.

         

        The 'myDataArray' needs to be prepopulated first and

        that array needs to already be in your tableView.

         

        Then this code will run.

         

        This is for macOS.

         

        // -----------------------------------------------------------
        // -- Getting data values from a tableView
        // -----------------------------------------------------------
        import Cocoa
        import Foundation
        
        extension MainViewController {
            // -----------------------------------------------------------
            // -- Note: that myDataArray is loaded and in memory.
            // -- That data is now showing inside of the tableView.
            // -- Now we want to do something with the rows the user
            // -- has selected.
            // -- also note: I'm only accessing a single column tableView.
            // -----------------------------------------------------------
        
            func tableViewSelectionDidChange(_ notification: Notification) {
                // -----------------------------------------------------------
                // -- This is an array to store the selected rows data.
                // -- In my case this is actually an instance array
                // -- in which I call .removeAll() on like this
                // -- myDataArray.removeAll()
                // -----------------------------------------------------------
                selectedRowsData[String] = []
        
                // -----------------------------------------------------------
                // -- Get the set of indexes for the rows that are selected.
                // -----------------------------------------------------------
                // -- myTableView.selectedRowIndexes
                // --    this is an index set containing
                // --    the indexes of the selected rows
                let selectedIndexSet = myTableView.selectedRowIndexes    
               
                // -----------------------------------------------------------
                // -- If your curious this is the quantity of rows selected.
                // -- I will be looping through this set in a moment.
                // -- SelectedIndexSet returns '# indexes' literally.
                // -- This index set contains something like ["2", "5", "9"]
                // -- uncomment the print line to see the number of
                // -- highlited rows
                // -- etc...
                // -----------------------------------------------------------
                // print("selectedIndexSet: There are \(selectedIndexSet)")
               
                // -----------------------------------------------------------
                // -- Now loop through the index set and extract
                // -- from the original data array "myDataArray",
                // -- the value that each row index points to.
                // -----------------------------------------------------------
                for index in selectedIndexSet {
                    // -- This line is here in case no rows are highlited.
                    // -- If no rows are highlited index will be -1
                    // -- If index has a value less than zero this routine
                    // -- will crash. 
                    // -----------------------------------------------------------
                    if index > -1 {
                        // -----------------------------------------------------------
                        // -- Append the actual data to selectedRowsData array
                        // -- This will provide quoted string, comma separated values.
                        // -- ["dataA", "dataB", "more data here"]
                        // -----------------------------------------------------------
                        selectedRowsData.append(myDataArray.self[index])
                    }
                }
                print("selectedRowsData \n \(selectedRowsData)")
            }
        }
        • Re: Get data from table
          Claude31 Level 8 Level 8 (9,215 points)

          Great you've learned something.

           

          But what was the point ? I must be missing something.

          You have TableView properties that can be used directly like

          var indexPathsForSelectedRows: [IndexPath]?

           

          Didn't it work ?

            • Re: Get data from table
              BBExploration Level 1 Level 1 (0 points)

              I am just starting in this language.  Feel free to elaborate.

              Assume a tablename of 'myTable' and a dataSource of 'myDataSourceArray'

              Now, what is the command to access the cell data? I'm using Swift, Xcode 11.1

                • Re: Get data from table
                  Claude31 Level 8 Level 8 (9,215 points)

                  You should look at tutorial, but the principle is simple.

                   

                  You declare how many sections and cells per section:

                  Here, if you have a single section with all the data of the dataSource:

                      func numberOfSections(in tableView: UITableView) -> Int {
                          return 1
                      }
                    
                      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                          return myDataSourceArray.count
                      }

                  You have a tableView func to populate the cells.

                  I assume that dataSource is an array of strings

                  If you have define the tableView cells with title and detail (a standard setup) and declared the identifier for cells as CellItem:

                   

                      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                       
                          let cell = tableView.dequeueReusableCell(withIdentifier: "CellItem", for: indexPath)
                       
                          // Configure the cell...
                          cell.textLabel!.text = "Cell \(indexPath.row+1)"     // Just show the cell number
                          cell.detailTextLabel?.text = myDataSourceArray[indexPath.row]     // The text in the array
                  
                          return cell
                      }

                   

                  When you want to modify the table, you usually modify the dataSource (array) and ask for tableView.reload()

                    • Re: Get data from table
                      BBExploration Level 1 Level 1 (0 points)

                      I think I see our differences.  I'm using NSView.  NSView is used for Mac.  UIView is used for IOS.  I'm not coding IOS.

                      In any event, what I have works well.  Thanks for the responses.

                       

                      https://stackoverflow.com/questions/5283218/what-is-the-difference-between-uiview-and-nsview

                        • Re: Get data from table
                          Claude31 Level 8 Level 8 (9,215 points)

                          Sure, but the principle is exactly the same.

                           

                          Just API are slightly different (notably because NSTables may have multiple columns

                           

                              func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
                                          if let cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "CellItem"), owner: self) {
                                              (cellView as! NSTableCellView).textField?.stringValue = myDataSourceArray[row]
                                              return cellView
                                          } else {
                                              return nil
                                          }
                          }

                          ANyway, you could now close the thread.

                  • Re: Get data from table
                    PBK Level 7 Level 7 (3,795 points)

                    A bit esoteric but let me suggest that you look at the question a bit differently:

                     

                    >getting data values from a tableView

                     

                    Under "Model-View-Controller" logic this is ass-backwards.  Your Model knows the data values.  Your Controller then displays those values in your View - your TableView.  There should never be a need to 'get values from a tableView'.  Just like there is no need for your mouth to 'know' what you are speaking.  You do need to know how to display data values from your Model in a tableView and you do that through the Controller's cellForRowAtIndexPath.