Pregunta

Tengo una vista compleja de iPad que administro con varios controladores de vista.Anteriormente (antes de iOS6/XCode 4.5) hice esto asignando mis controladores de vista en el código y conectándoles las distintas vistas a través de enlaces a la vista maestra.

Lo que me gustaría hacer es usar las nuevas vistas del contenedor para incrustar los controladores de vista en el archivo del guión gráfico.Parece que no puedo establecer un enlace IBOutlet entre el controlador de vista integrado y el controlador maestro.

¿Es posible hacer esto?¿O recuperar el controlador integrado mediante una etiqueta o algo en el código?

Esta pregunta es ESPECÍFICAMENTE sobre el uso de vistas de contenedor.

¿Fue útil?

Solución

No estoy seguro de lo que quiere decir con "recuperar el controlador incrustado".Cuando quiera usar un controlador, usa el método de Uistoryboard InstantiateViewControllerWithIdentifier:, usando el identificador que le da al controlador en IB.También puede usar el Método Sembrador: Sender: Method (que también instanció el controlador de vista).Debe revisar la sección "Uso de los controladores de vista en su aplicación" en Apple Docs.También hace referencia al hecho de que los controladores de vista infantil se instancian al mismo tiempo que el controlador del contenedor.

Después de la edición: si inserta una vista de contenedor en otro controlador de vista, el controlador de la Vista incorporada se puede hacer referencia desde el controlador que contiene con self.childViewControllers (que será una matriz, por lo que si es solo uno, puede obtenerlocon el último objeto).

Otros consejos

Otra opción para algunos casos es capturar el controlador integrado usando -prepareForSegue:sender:.

Por ejemplo, si tengo un UINavigationController incrustado dentro de un CustomContainerViewController, puedo nombrar la transición de inserción embedContentStack en el guión gráfico y capturarlo en CustomContainerViewController a través de

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"embedContentStack"]) {
        // can't assign the view controller from an embed segue via the storyboard, so capture here
        _contentStack = (UINavigationController *)segue.destinationViewController;
    }
}

Nota de precaución

Antes de proceder a utilizar una respuesta a esta pregunta, es posible que desee reflexionar si las cosas incrustadas realmente necesitan ser controladores de vista.

Por ejemplo, si está incrustando un UICollectionViewController subclase, ¿podrías en su lugar incrustar una UICollectionView subclase?O, mejor aún, ¿podrías insertar un UIView subclase que esconde el UICollectionView detrás de un modelo de vista simple?

En el código base en el que estoy trabajando actualmente, estoy incorporando dos controladores de vista en otro controlador de vista.En su lugar, ambas podrían ser vistas simples y luego podrían vincularse más fácilmente en el guión gráfico, sin este código desordenado.

Desafortunadamente, actualmente son controladores de vista y no estoy en condiciones de simplificarlos a vistas simples en este momento, así que esto será suficiente.

Fondo

Estoy usando el enfoque de retomar la transición de inserción en prepare(for segue:, sender:) como lo sugiere Friki juguetón aquí.

Quería mostrar el veloz que estoy usando para esto, ya que parece estar bastante ordenado...

class EditionLandingViewController: UIViewController {
    fileprivate var titlesView: SectionTitlesViewController!
    fileprivate var sectionsView: SectionsViewController!
}

//MARK:-

extension EditionLandingViewController {
    private enum SegueId: String {
        case embedTitles
        case embedSections
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        guard
            let segueRawId = segue.identifier,
            let segueId = SegueId(rawValue: segueRawId)
            else { return }

        switch segueId {
        case .embedTitles:
            self.titlesView = segue.destination as! SectionTitlesViewController

        case .embedSections:
            self.sectionsView = segue.destination as! SectionsViewController
        }
    }
}

Discusión

he elegido nombre segues como métodos de acción.

Usando un enum Los casos para identificadores de transición significan que tiene el compilador y las herramientas de su lado, por lo que es mucho más difícil equivocarse en un nombre de transición.

Mantener los identificadores de transición en un private enum dentro de extension El alcance parece apropiado en este caso ya que estas transiciónes no son necesarias en ningún otro lugar (no pueden ser performed, por ejemplo).

Estoy usando tipos implícitamente desenvueltos para los controladores de vista integrados porque (al menos en mi caso) es un error lógico si faltan.

De manera similar, también me complace forzar la conversión de los tipos de controlador de vista de destino.Nuevamente, sería un error lógico si estos tipos no fueran iguales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top