2015-02-19 10 views
5

Sto cercando di trovare una soluzione a questa situazione:
Ho un UITabBarController uno dei suoi passaggi è connesso a un controller di visualizzazione contenitore (BannerViewController) che sto usando per incorporare un UINavigationController, il controller di navigazione spinge altri controller di visualizzazione contenitori (EventListContainerviewController) ognuno di questi contiene un controller tableview.
Qui una schermata del mio pannello di storia enter image description here
Il problema è che l'ultima vista del contenitore viene visualizzata in un frame più piccolo rispetto ai contenitori. Sembra che perdano lo spazio delle tabulazioni in basso. enter image description here
Ho forzato tutti i controller di vista, il controller di navigazione e il controller Tabbar per evitare di non estendere i bordi e regolare gli inserti.UINavigationController incorporato in una vista contenitore, visualizza un controller Vista tabella con dimensioni errate

Il colore significa:

Rosso: vista principale del BannerContainerViewController 0x7fcc6d38bb00
luce verde: la vista del contenitore del BannerContainerViewController 0x7fcc6d38b860

Blu: vista principale del EventListContainerViewController 0x7fcc6bd7b7c0
Arancione : la vista container di EventListContainerViewController 0x7fcc6bd7b690

Sembra che qualcosa cambi quando il controller di navigazione aggiunge la vista del contenitore blu riducendo le sue dimensioni della stessa quantità di una tabbar (49pt). Si può notare anche nella descrizione ricorsiva della gerarchia vista:

<UIWindow: 0x7fcc6bd5af40; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7fcc6bd4dd80>; layer = <UIWindowLayer: 0x7fcc6bd317c0>> 
    | <UILayoutContainerView: 0x7fcc6bd671c0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7fcc6bd66de0>> 
    | | <UITransitionView: 0x7fcc6bd6a980; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7fcc6bd6ace0>> 
    | | | <UIViewControllerWrapperView: 0x7fcc6d3a7b20; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7fcc6d3a7db0>> 
    | | | | <UIView: 0x7fcc6d38bb00; frame = (0 0; 320 519); autoresize = W+H; layer = <CALayer: 0x7fcc6d38bbd0>> 
    | | | | | <UIView: 0x7fcc6d38b860; frame = (0 0; 320 519); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fcc6d38b930>> 
    | | | | | | <UILayoutContainerView: 0x7fcc6d398000; frame = (0 0; 320 519); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fcc6d3a4b50>; layer = <CALayer: 0x7fcc6d387670>> 
    | | | | | | | <UINavigationTransitionView: 0x7fcc6d39cfa0; frame = (0 0; 320 519); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7fcc6d39cc40>> 
    | | | | | | | | <UIViewControllerWrapperView: 0x7fcc6bf31230; frame = (0 0; 320 519); autoresize = W+H; layer = <CALayer: 0x7fcc6bf31300>> 
    | | | | | | | | | <UIView: 0x7fcc6bd7b7c0; frame = (0 64; 320 406); autoresize = W+H; layer = <CALayer: 0x7fcc6bd7afe0>> 
    | | | | | | | | | | <UIView: 0x7fcc6bd7b690; frame = (0 0; 320 406); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fcc6bd7aac0>> 
    | | | | | | | | | | | <UITableView: 0x7fcc6f03c400; frame = (0 0; 320 406); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fcc6bf34aa0>; layer = <CALayer: 0x7fcc6bf30bc0>; contentOffset: {0, 0}; contentSize: {320, 170}> 
    | | | | | | | | | | | | <UITableViewWrapperView: 0x7fcc6bf35960; frame = (0 0; 320 406); gestureRecognizers = <NSArray: 0x7fcc6bf363e0>; layer = <CALayer: 0x7fcc6bf35ed0>; contentOffset: {0, 0}; contentSize: {320, 406}> 
    | | | | | | | | | | | | | <EventCell: 0x7fcc6bca2950; baseClass = UITableViewCell; frame = (0 85; 320 85); autoresize = W; layer = <CALayer: 0x7fcc6bca2ca0>> 

ho tenta di utilizzare personalizzato Segue al posto di vista contenitore cercare di forzare il layout, ma credo che è un difetto controller di navigazione.
Come si può vedere il banner non si sovrappone alla vista come previsto.
enter image description here

Qualsiasi suggerimento?

+0

Hai controllato che il tuo viewcontroller abbia l'opzione 'Estendi bordi UnderBottomBars' selezionata? – las

+0

sicuro come ho scritto nella domanda – Andrea

+0

ops ... hanno tutti i bordi avanzati deselezionati – Andrea

risposta

3

scopre che è un bug UIKit, ho presentato una radar 19996374. Ecco la spiegazione:

Quando un controller di navigazione è posta all'interno di un controller barra delle schede, responsabilità per la posa fuori il contenuto (il tuo) controller di visualizzazione è dato completamente al controller di navigazione. Il controller della barra delle schede consente di ridimensionare la vista del controller di navigazione in modo che corrisponda ai limiti di visualizzazione del controller della barra delle schede . A turno, gli account del controller di navigazione per l'altezza della barra delle schede quando si espande il controller della vista del contenuto. Le cose si interrompono quando si inietta un controller di visualizzazione tra la barra delle schede e il controller di navigazione. Il controller della barra delle schede vede che il ViewController selezionato non è un UINavigationController e applica le normali regole di layout.Ma contenuta controller di navigazione vede che la sua proprietà tabBarController contiene una valida esempio UITabBarController e si presuppone che è ancora responsabile per la gestione l'altezza barra delle schede quando si posa il contenuto (il vostro) View Controller. Il risultato è che il controller di vista dei contenuti è INSET dall'altezza scheda bar due volte, come hai osservato

Come soluzione

È possibile aggirare il problema impostando la proprietà isTranslucent di la barra delle schede su SÌ. Quindi, in AFBannerViewController, eseguire l'override di -edgesForExtendedLayout per restituire UIRectEdgeAll. AFBannerViewController ora si sovrapporrà alla barra delle schede (quindi imposta il colore dello sfondo su qualcosa di diverso dal rosa), ma il controller di navigazione applicherà l'intestazione corretta al controller della vista del contenuto.

+1

Ad oggi questo bug esiste ancora (test con iOS 9, Xcode 7.3 e Swift 2) . Traslucido + colore di sfondo sulla vista della barra delle schede + edgesForExtendedLayout to. All fa sì che tutto funzioni di nuovo. Grazie. –

+0

Purtroppo il mio errore è fino a "richiedere ulteriori informazioni" anche se ho inviato un piccolo progetto che mostra il problema. – Andrea

5

Questo problema esiste ancora in IOS 10. UINavigationController incorporato in una vista del contenitore, a sua volta contenuto in un'UITabBarController, porrà tutte viste in stack di spostamento con spazio per un "fantasma" barra delle schede in basso.

La soluzione più semplice è sottoclasse UINavigationController e restituisce 'nil' da tabBarController.

class MyNavigationController: UINavigationController { 

    override var tabBarController: UITabBarController? { 
     return nil 
    } 

} 

questo rende il punto di vista dello stack di navigazione pensare di non avere un controller barra delle schede, in modo da non lasciare spazio extra per questo durante il layout. Non ho notato effetti collaterali negativi da questa correzione, ma ovviamente le viste nello stack di questo controller di navigazione non avranno più accesso al controller della barra delle linguette. Se questo è un problema, puoi utilizzare un metodo più generico per trovare il controller della barra delle schede (o qualsiasi controller di visualizzazione "principale").

Ad esempio, se il controller di visualizzazione principale per l'app è UITabBarController denominato "MainViewController", è possibile estendere UIViewController con un comodo metodo per trovarlo.

extension UIViewController { 

    func mainViewController() -> MainViewController? { 
     var vc: UIViewController? = self 
     while !(vc is MainViewController) && vc != nil { 
      vc = vc?.parent ?? vc?.navigationController ?? vc?.presentingViewController 
     } 
     return vc as? MainViewController 
    } 

} 

Questo funziona perché un controller barra delle schede è il parent dei suoi controllori diretti Bambini. Il metodo sopra riportato si sviluppa lungo la catena di controller parent, present e nav per raggiungere infine un figlio del controller della barra delle schede, che restituisce il controller della barra delle schede come genitore.

+0

Questo è un approccio interessante, ma sono molto turbato dal fatto che Apple non sembra avere alcun interesse a risolverlo. Ti suggerisco di presentare un bug. – Andrea

+0

Beh, parecchie ore di dolore dopo ho deciso di cercare lo stack traboccante e l'hai risolto per me in un minuto. Vorrei poterti dare tutti i voti. –

Problemi correlati