以编程方式更改 TabViewController 中的选定选项卡

Changing Selected Tab in TabViewController Programmatically

我有一个 OS Mac 应用程序,在我的顶级视图控制器中有两个按钮和一个容器视图。我用选项卡视图控制器将视图控制器 link 替换为容器视图。我想使用顶层视图控制器中的按钮切换选项卡。我让它接近工作的唯一方法是按如下方式设置按钮操作:

@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。这是在我添加设置它的指令之前。无论如何,代码不会更改选项卡。实例化控制器似乎不正确,因为视图出现时没有单击按钮。该调用是否仅用于 return 一个 link 而不是实例化一个新对象?有更直接的方法吗?

我尝试了这个问题的答案:。它产生了一个错误,说它 tabViewController 未解决。我已将 TabViewController 的故事板 ID 设置为 tabViewController。

更新

我补充了:

self.selectedTabViewItemIndex = 0

到我创建的 class 中的 viewDidLoad 方法并 linked 到 TabViewController。当我 运行 应用程序时,索引已更改,但仍显示最后一个选项卡 (2)。当我单击 window 中的选项卡 0 时,选项卡发生变化,但索引的显示保持不变。似乎我可能调用了错误的方法,尽管 none 对其他人来说似乎是合适的。

进度

我将 NSTabViewController class 更改为:

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

这是上述解决方案 link 的答案。它在控制器 linked 到控件中工作正常,但在主控制器按钮操作方法中不起作用。这让我觉得我已经实例化了 class.

的第二个实例

添加计时器解决了切换标签页的直接问题。我通过使用委派模式的一个稍微被破解的版本解决了让按钮进行切换的问题。

代码显示在我关于让它工作的问题中:

这就是我解决选项卡切换(和(重新)恢复)的方法

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