Iboutlet Link al controller di visualizzazione incorporato
-
12-12-2019 - |
Domanda
Ho una visione di iPad complessa che gestisco avendo diversi controller di visualizzazione.In precedenza (prima IOS6 / XCode 4.5) ha fatto questo allocando i controller di visualizzazione nel codice e collegarli le varie opinioni per loro anche se i collegamenti con la vista principale.
Quello che vorrei fare è utilizzare le nuove viste del contenitore per incorporare i controller di visualizzazione nel file dello storyboard.Non sembra essere in grado di creare un collegamento IBoutlet al controller di visualizzazione incorporato al controller principale.
È possibile farlo?O per recuperare il controller incorporato tramite un tag o qualcosa nel codice?
Questa domanda è specificatamente sull'utilizzo delle viste del contenitore
Soluzione
Non sono sicuro di cosa intendi per "recuperare il controller incorporato".Quando si desidera utilizzare un controller, si utilizza il metodo UistoryBoard istanziateViewControllerWithIdentifier:, utilizzando l'identificatore da fornire al controller in Ib.È inoltre possibile utilizzare il performSuewithIdentifier: Sender: Metodo (che ha anche istanziato il controller di visualizzazione).È necessario controllare la sezione "Uso dei controller di visualizzazione nella tua app" nei documenti Apple.Fa anche riferimento al fatto che i controller di visualizzazione dei bambini vengono istanziati allo stesso tempo del controller del contenitore.
After Modifica: Se si è incorporata una vista contenitore in un altro controller di visualizzazione, che il controller di vista incorporato può essere referenziato dal controller contenente con Self.ChildViewControllers (che sarà un array, quindi se ce n'è solo uno, puoi ottenerlo solocon lastobject).
Altri suggerimenti
Un'altra opzione per alcuni casi è quella di catturare il controller incorporato utilizzando -prepareForSegue:sender:
.
Ad esempio, se ho un UINavigationController
incorporato all'interno di un CustomContainerViewController
, posso nominare il sesto incorporato embedContentStack
nello Storyboard e acquisirlo in CustomContainerViewController
tramite
- (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;
}
}
. Ecco un altro thread a riguardo: Access Contenitore Visualizza controller dal genitore IOS
Propongono di mantenere un riferimento in prememorseescue o cercare il viewcontroller incorporato in Self.ChildViewControllers
nota di cautela
Prima di procedere a utilizzare una risposta a questa domanda, potresti voler riflettere se le cose incorporate hanno davvero bisogno di essere visualizzare i controllori.
Ad esempio, se stai incorporando una sottoclasse UICollectionViewController
, potresti invece incorporare una sottoclasse UICollectionView
? O, ancora meglio, potresti incorporare una sottoclasse UIView
che nasconde il UICollectionView
dietro un semplice quadro di vista?
Nella base di codice attualmente sto lavorando, sto incorporando due controller di visualizzazione in un altro controller di visualizzazione. Entrambi potrebbero essere piuttosto facilmente semplici punti di vista, e potrebbero quindi essere più facilmente vincolati nello storyboard, senza questo codice disordinato.
Sfortunatamente, sono attualmente vedi i controller e non sono in grado di semplificarli in una vista semplice in questo momento, quindi questo dovrà fare.
Sfondo
Sto usando l'approccio di raccogliere il segue incorporato in prepare(for segue:, sender:)
come suggerito da giocoso Geek qui. .
Volevo mostrare il Swift che sto usando per questo, come sembra essere abbastanza ordinato ...
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
}
}
}
.
Discussione
Ho scelto di nome seguisi come metodi di azione .
Utilizzando un custodie enum
per identificatori segue significa che hai il compilatore e l'utensili dalla tua parte, quindi è molto più difficile ottenere un nome sesto sbagliato.
Mantenere gli ID segue in un private enum
nell'ambito dell'ambito extension
sembra appropriato in questo caso in quanto questi segmenti non sono necessari da nessun'altra parte (non possono essere generacolitagCodeed, ad esempio).
Sto usando tipi implicitamente non confezionati per i controller di visualizzazione incorporati perché (nel mio caso comunque) è un errore logico se mancano.
Allo stesso modo, sono anche felice di forzare il lancio dei tipi di controllo della vista Destinazione. Di nuovo, sarebbe un errore logico se questi tipi non sono uguali.