Как вставить строку в tableView без использования функции reloadData в Cocoa

Я работал над самостоятельным проектом в Cocoa. Попытка воспроизвести, как работает список воспроизведения медиаплеера (воспроизведение, добавление и удаление и т. д.).

До сих пор мне удалось заполнить табличное представление из каталога, используя NSOpenPanel. Я могу вставить новые файлы в таблицу и воспроизвести выбранные звуковые файлы, используя AVAudioPlayer. Все работает так, как ожидалось.

Но когда я пытаюсь вставить новую строку в tableView во время воспроизведения audioPlayer. Он обновляет весь tableView, и я получаю следующие проблемы.

  • audioPlayer остановился, как только обновление было выполнено.
  • Воспроизведение выбранного медиафайла не выбрано.

Мой частичный код ниже:

   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()
     }
   }

Как мне обновить tableView, добавив или удалив строку во время работы audioPlayer, а не перезагружать все tableview.

Я провел некоторые исследования, как показано ниже, и нашел вопрос, аналогичный вышеуказанным проблемам. Но это не помогло мне полностью решить проблему.

Как обновить NSTableView без использования -reloadData?

перезагрузить данные в NSTableView, но сохранить текущий выбор

Apple Doc — reloadData(forRowIndexes:columnIndexes:)

Я новичок в разработке macOS. Итак, помогите мне понять проблему и как ее исправить.


Обновление:

Ниже код решает часть проблемы, упомянутой выше. Использование приведенного ниже кода сохраняет выделение выбранной строки после обновления.

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

Но все же audioPlayer по какой-то причине остановился после вставки новой строки. мой код audioPlayer, как показано ниже

В ViewDidLoad: (метод действия)

 tableView.doubleAction = #selector(tableViewClick)

Код селектора:

 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")
    }
}

Попытка обновить строку/столбец только с помощью reloadData(forRowIndexes:columnIndexes:). Но, похоже, не работает...

  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)

Обновление: Проблема решена:

Проблема решена после предложения @Leo Dabus и его принятого ответа из этого сообщения BLE Peripheral отключается при переходе к другому ViewController . Я создал класс Singleton, как показано ниже.

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

И получите доступ к тому же экземпляру, что и ниже.

Shared.instance.audioPlayer = audioPlayer

Надеюсь, это поможет кому-то....


person Joe    schedule 26.11.2017    source источник
comment
Почему AVAudioPlayer останавливается? он принадлежит tableViewCell? если это так, возможно, переместите его в контроллер представления или в класс AudioPlayerPool и делегируйте ответственность за запуск проигрывателя.   -  person Josh Homann    schedule 26.11.2017
comment
спасибо за предложение. я попробую, и у меня нет отдельного класса для AudioPlayer. но у меня есть метод действия tableview в viewDidLoad tableView.action = #selector(tableViewClick)   -  person Joe    schedule 26.11.2017
comment
Новые строки автоматически обновляются. Просто вставьте или удалите строку.   -  person Willeke    schedule 27.11.2017
comment
@Willeke Спасибо. У меня нет проблем с вставкой или удалением строк. Проблема в том, почему audioPlayer перестает работать после вставки строки. проверьте мое обновление и дайте мне знать о комментарии.   -  person Joe    schedule 27.11.2017
comment
Почему вы делаете reloadData?   -  person Willeke    schedule 27.11.2017
comment
@Willeke Спасибо. Я немного смущен. как я могу добавить новую строку без функции перезагрузки. я пробовал без функции перезагрузки, но ничего не вызывается...   -  person Joe    schedule 27.11.2017
comment
Вставьте строку в табличное представление с помощью insertRows(at:withAnimation:).   -  person Willeke    schedule 27.11.2017