Tengo una aplicación OS Mac con dos botones y una vista de contenedor en mi controlador de vista de nivel superior. Reemplacé el controlador de vista vinculado a la Vista de contenedor con un Controlador de vista de pestaña. Me gustaría cambiar de pestaña usando los botones en el controlador de vista de nivel superior. La única forma en que lo tengo cerca de funcionar es configurando las acciones del botón de la siguiente manera:

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

La llamada de instanciación parece funcionar porque, cuando agregué una tercera pestaña, el recuento cambió de 1 a 2. Esto fue antes de agregar la instrucción para configurarlo. En cualquier caso, el código no cambia la pestaña. Crear una instancia del controlador no parece correcto porque la vista aparece sin hacer clic en el botón. ¿La llamada solo tiene la intención de devolverle un enlace y no crear una instancia de un nuevo objeto? ¿Existe una forma más sencilla de hacerlo?

Probé la respuesta de esta pregunta: Cambiar la barra de pestañas mediante programación en Swift. Generaba un error que decía que tabViewController no estaba resuelto. He configurado la identificación del guión gráfico del TabViewController en tabViewController.

Actualizar

Yo añadí:

self.selectedTabViewItemIndex = 0

Al método viewDidLoad en una clase que creé y vinculé al TabViewController. Cuando ejecuto la aplicación, el índice cambia, pero la última pestaña (2) todavía se muestra. Cuando hago clic en la pestaña 0 en la ventana, la pestaña cambia, pero la visualización del índice sigue siendo la misma. Parece que puedo estar llamando al método incorrecto, aunque ninguno para los demás parece apropiado.

Progreso

Cambié mi clase NSTabViewController a:

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

Esta es una respuesta de la solución vinculada anteriormente. Funciona bien en el controlador vinculado al control, pero no en los métodos de acción del botón del controlador principal. Me hace pensar que he creado una segunda instancia de la clase.

1
curt 15 dic. 2016 a las 08:44

2 respuestas

La mejor respuesta

Agregar el temporizador solucionó el problema inmediato de cambiar de pestaña. Resolví conseguir que los botones hicieran el cambio usando una versión ligeramente pirateada del patrón de delegación.

El código se muestra en mi pregunta sobre cómo hacer que funcione: Obtención de una referencia de controlador de vista

0
pkamb 27 mar. 2020 a las 08:12

Así es como resolví el cambio de pestañas (y (re) almacenamiento)

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
        }
    }
}
1
schmidt9 3 ago. 2020 a las 18:18