Изменение выбранной вкладки в TabViewController программно

У меня есть приложение для Mac OS с двумя кнопками и Контейнерное Представление в моем Контроллере Представления верхнего уровня. Я заменил контроллер представления, связанный с представлением контейнера, контроллером представления представления. Я хотел бы переключать вкладки с помощью кнопок на верхнем уровне View Controller. Единственный способ приблизить его к работе - настроить действия кнопок следующим образом:

@IBAction func selectCompositions(_ sender: NSButton) {
  let tabViewController = self.storyboard?.instantiateController(withIdentifier: "tabViewController") as!NSTabViewController
  tabViewController.selectedTabViewItemIndex = 2
  let count = tabViewController.selectedTabViewItemIndex
  print(count)
}

Вызов экземпляра работает, потому что, когда я добавил третью вкладку, счетчик изменился с 1 на 2. Это было до того, как я добавил инструкцию для его установки. Во всяком случае, код не меняет вкладку. Инстанцирование контроллера не кажется правильным, потому что представление появляется без нажатия кнопки. Предназначен ли вызов только для того, чтобы вернуть ссылку на него, а не для создания нового объекта? Есть ли более прямой способ сделать это? Я попробовал ответ на этот вопрос. Это сгенерировало ошибку, говоря, что tabViewController был не решен. Я установил идентификатор раскадровки TabViewController для tabViewController.

Обновить

Я добавил:

self.selectedTabViewItemIndex = 0

к методу viewDidLoad в классе, который я создал и связал с TabViewController. Когда я запускаю приложение, индекс изменяется, но последняя вкладка (2) по-прежнему отображается. Когда я нажимаю на вкладку 0 в окне, вкладка изменяется, но отображение индекса остается прежним. Кажется, что я могу вызывать неправильный метод, хотя ни один из них не кажется подходящим.

Прогресс

Я изменил свой класс NSTabViewController на:

class TabViewController: NSTabViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.
    print("In TabViewController")
    switchToDataTab()
  }

  func switchToDataTab() {
    Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(switchToDataTabCont), userInfo: nil, repeats: false)
  }  

  func switchToDataTabCont(){
    self.selectedTabViewItemIndex = 2
  }
}

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

1 ответ

Решение

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

Вот как я решил переключение вкладок (и (повторное) хранение)

import Foundation
import Cocoa

class TabViewController: NSTabViewController {

    private var isLoading = false

    /// Use with Selected Index binding of NSTabView
    /// because setting binding direct to UserDefaults does not work
    @objc var selectedTabIndex: Int = 0 {
        didSet {
            if !isLoading {
                UserDefaults.standard.set(selectedTabIndex, forKey: "selectedTabIndex")
            }
        }
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // set flag before selectedTabIndex binding fires to prevent setting overwrite
        isLoading = true
    }

    override func viewWillAppear() {
        super.viewWillAppear()

        if isLoading {
            selectedTabViewItemIndex = UserDefaults.standard.integer(forKey: "selectedTabIndex")
            isLoading = false
        }
    }
}
Другие вопросы по тегам