How to insert a row in tableView without using rel

2019-08-17 13:43发布

问题:

I been working on a self taught project in Cocoa. Trying to replicate how the media player playlist works(Play,Add and Delete and etc...).

So far, I have managed to populate a tableview from the directory using NSOpenPanel. I can able to insert a new files to the tableview and play selected sound files using AVAudioPlayer. Everything works as expected.

But When, I try to insert a new row to the tableView while the audioPlayer is playing. It updates the entire tableView and i am getting the following issues.

  • audioPlayer stopped as soon as the update performed.
  • Playing selected media file left unselected.

My Partial code below:

   var items: [URL] = [] {
   didSet {    
          tableView.beginUpdates()
          tableView.reloadData(forRowIndexes: tableView.selectedRowIndexes, columnIndexes: tableView.selectedColumnIndexes)
          tableView.reloadData()//Trying to avoid this func...
          tableView.selectRowIndexes(tableView.selectedRowIndexes, byExtendingSelection: true)
          tableView.endUpdates()
     }
   }

How do i update the tableView by adding or deleting row while the audioPlayer performing and not to reload the entire tableview.

I have done some research as below and found similar question to above issues. But it didn't helped me to fix the issue entirely.

How to update NSTableView without using -reloadData?

reloadData in NSTableView but keep current selection

Apple Doc - reloadData(forRowIndexes:columnIndexes:)

I am new to macOS development. So, help me to understand the issue and how to fix it.


Update:

Below code solves part of the issue mentioned above. Using below code keeps the selected row highlighted after update.

  var items: [URL] = [] {
  didSet {    
      let selectedRowIndexes = self.tableView.selectedRowIndexes
      tableView.reloadData()
      tableView.selectRowIndexes(selectedRowIndexes, byExtendingSelection: true)
     }
   }

But, Still audioPlayer stopped after inserting new row for some reason. my audioPlayer code as below

In ViewDidLoad: (action method)

 tableView.doubleAction = #selector(tableViewClick)

Selector code:

 func tableViewClick(_ sender: AnyObject) {
    if tableView.selectedRow < 0 { return }
    let selectedItem = items[tableView.selectedRow]
    print(selectedItem)
    do{
        try self.audioPlayer = AVAudioPlayer.init(contentsOf: selectedItem)
        audioPlayer.delegate = self
        audioPlayer.play()
    }
    catch {
        print("Error reading file attributes")
    }
}

Trying to update row/column only using reloadData(forRowIndexes:columnIndexes:). But, it not seems to be working...

  tableView.reloadData(forRowIndexes: NSIndexSet(index: tableView.selectedRowIndexes.count) as IndexSet, columnIndexes: NSIndexSet(index: tableView.selectedColumnIndexes.count) as IndexSet)  

or

  tableView.reloadData(forRowIndexes: tableView.selectedRowIndexes, columnIndexes: tableView.selectedColumnIndexes)

Update: Issue Resolved:

Issue resolved after @Leo Dabus suggestion and his accepted answer from this post BLE Peripheral disconnects when navigating to different ViewController . I created Singleton class as below

class Shared { 
    private init(){ } 
    static let instance = Shared()
    var audioPlayer = AVAudioPlayer()
}

And access the same instance as below.

Shared.instance.audioPlayer = audioPlayer

Hope this helps someone....