2013-10-02 17 views
54

Ho UITabbarController con UINavigationController in esso. Ho una sottoclasse di UIView che assegno come view di UIViewController nello navController. Questa è roba abbastanza standard, giusto? Questo è come lo faccioPerché UIViewController si estende sotto UINavigationBar, mentre UITableViewController no?

_productCategoryView = [[ProductCategoryView alloc] initWithFrame:self.view.frame]; 
self.view = _productCategoryView; 

Questo view ha una UITableView come subView

_productCategoryTableView = [[UITableView alloc] initWithFrame:self.frame style:UITableViewStylePlain]; 
_productCategoryTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 
_productCategoryTableView.backgroundColor = [UIColor clearColor]; 
[self addSubview:_productCategoryTableView]; 

Per motivi di debug io pongo self.backgroundColor = [UIColor blueColor] sulla vista.

Dalla suddetta inizializzazione di tableView si potrebbe pensare che la vista e la tabella frame siano uguali. Tuttavia, quando corro in iOS 7, l'origine della vista viene impostata dietro allo UINavigationBar. Questo è comprensibile perché sto impostando self.navigationBar.translucent = YES; nella sottoclasse di UINavigationController. Ma quello che non capisco è come mai il tavolo è seduto appena sotto lo navBar? Non dovrebbe anche iniziare da (0, 0) che è dietro il navBar? Vedi screenshot Scenario 1 qui sotto. Si noti la tonalità blu dietro navBar

Scenario 1

Ora, io push un'altra viewController sullo stack di navigazione, semplicemente utilizzando [self.navigationController pushViewController.....]. Ancora una volta ho un UIView personalizzato con un tableView in esso. Tuttavia ho anche un UILabel sopra questa tabella, e ancora per il debug, ho dato un redColor. Questa volta io pongo del origin dell'etichetta da essere quasi uguale della vista

CGRect boundsInset = UIEdgeInsetsInsetRect(self.bounds, UIEdgeInsetsMake(10, 10, 10, 10)); 

CGSize textSize = [_titleLabel.text sizeWithFont:_titleLabel.font 
           constrainedToSize:CGSizeMake(boundsInset.size.width, MAXFLOAT) 
            lineBreakMode:NSLineBreakByWordWrapping]; 
printSize(textSize); 
_titleLabel.frame = CGRectMake(boundsInset.origin.x, 
           boundsInset.origin.y, 
           boundsInset.size.width, 
           textSize.height); 

Così, passando dalla logica sopra, l'etichetta deve essere visibile, giusto? Ma questa volta non lo è. Questa volta l'etichetta è dietro lo navBar.

Scenario - 2

Avviso, la tonalità rosso dietro navBar.

Mi piacerebbe molto allineare il subView sotto il navBar in modo coerente. Le mie domande sono

1. How is the tableView offset by 64pixels (height of nav + status bar in iOS 7) automatically, even though it's frame is same as the view's?

2. Why does that not happen in the second view?

+0

Stai creando Xcode 5 e iOS7 SDK ? –

risposta

128

Per impostazione predefinita, le opinioni di UITableViewController sono inseriti automaticamente nella iOS7 in modo che essi non iniziano al di sotto della barra di navigazione bar/stato. Questo è il controller tramite l'impostazione "Regola impostazioni scorrimento vista" nella scheda Impostazioni attributi di UITableViewController in Interface Builder o tramite il metodo setAutomaticallyAdjustsScrollViewInsets: di UIViewController.

Per il contenuto di un UIViewController, se non si vuole il contenuto del suo punto di vista di estendere sotto il top/bar in basso, è possibile utilizzare il Extend Bordi Sotto Migliore Bar/In Impostazioni Bar di fondo in Interface Builder. Questo è accessibile tramite la proprietà edgesForExtendedLayout.

+48

Grazie a @Greg. impostazione 'self.edgesForExtendedLayout = UIRectEdgeNone;' ha fatto il trucco. – unspokenblabber

+0

Grazie. L'indirizzamento di edgesForExtendedLayout completato ha risolto il problema del layout di uitableview-as-a-subview-of-navcontroller per me; aveva trascorso innumerevoli ore su questo negli ultimi 8 mesi. – ObjectiveTC

+1

Durante una transizione push con navigationController, ho notato che sulla barra di navigazione è applicato un trattamento del colore "ritardato". Cosa causa questo e come rimuoverlo? – ArdenDev

89
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.edgesForExtendedLayout = UIRectEdgeNone; 
} 

Swift 2:

self.edgesForExtendedLayout = UIRectEdge.None 

Swift 3:

self.edgesForExtendedLayout = [] 
+0

corretto, grazie! –

+1

La risposta più utile. – yujean

+0

L'impostazione 'self.edgesForExtendedLayout = []' cambia il colore 'UINavigationBar'. – Hemang

9

@ risposta di Gank è corretta, ma il posto migliore per farlo è sul UINavigationControllerDelegate (se ne avete uno) :

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { 
    viewController.edgesForExtendedLayout = UIRectEdge.None 
} 
+2

Ciò evita un controller Super View personalizzato. Così bello – Jaybo

+0

@Jaybo grazie, sì, dove hai messo il codice ha grandi implicazioni. –

Problemi correlati