solid guidelines color bar ios objective-c uitableview uinavigationbar

ios - guidelines - UITableView pasa por debajo de la barra de navegación translúcida



set navigation bar swift (12)

Introducción

Soy nuevo en el desarrollo de iOS y Stack Overflow, así que perdónenme si mi publicación no es perfecta.

También tuve este problema, y ​​cuando utilicé las inserciones de contenido para mi UITableView funcionó perfectamente al cargar primero, o al visitarlo desde mis otras pestañas; Sin embargo, si navegaba de regreso a la vista, tendría el "relleno" adicional. Me di cuenta de una solución alternativa, por lo que mi UITableView se colocará correctamente en todo momento.

La cuestión

Cuando carga por primera vez el UITableView, o la pestaña, necesita las inserciones para iniciar correctamente la tabla debajo de la barra de navegación, pero cuando navega hacia atrás no necesita las inserciones, porque por alguna razón, calcula correctamente para la ubicación de el UITableView. Es por eso que puedes obtener el relleno extra.

La solución

La solución implica el uso de un booleano para determinar si se ha navegado, de modo que pueda determinar correctamente si necesita las inserciones de contenido o no.

En -(void)viewDidLoad configuré hasNavigatedFurther = NO . Entonces:

-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (!hasNavigatedFurther) { self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); } else { self.tableView.contentInset = UIEdgeInsetsZero; //In order to allow visiting between tabs and retaining desired look hasNavigatedFurther = NO; } }

Para que esto funcione, debe establecer hasNavigatedFurther = YES justo antes del código que empuja otra vista a la pila de navegación.

-(void)btnTouched:(id)sender { hasNavigatedFurther = YES; NextViewController* nvc = [NextViewController new]; [self.navigationController pushViewController:nvc animated:YES]; }

Intento tener una barra de navegación transparente en la aplicación IOS 7. Hay una imagen de pantalla completa en mi aplicación. También estoy teniendo UITableView sobre esa imagen. Cuando uso el código a continuación, la imagen se ajusta a la pantalla como quiero, pero UITableView va debajo de la barra de navegación.

en viewDidLoad

yo suelo

self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationController.navigationBar.translucent = YES; self.navigationController.view.backgroundColor = [UIColor clearColor];

está bien cuando cambio a self.navigationController.navigationBar.translucent = NO; pero luego pierdo transparencia en la barra de navegación.


Combiné las soluciones de @Adam Farrell y @Tash Pemhiwa, y finalmente el código siguiente funciona para mí:

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self adjustEdgeInsetsForTableView]; } - (void)adjustEdgeInsetsForTableView { if(self.isMovingToParentViewController) { self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); } else { self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); } }

Espero que esto ayude a las personas que pierden un par de horas en este extraño comportamiento de UI.


Es mejor no codificar los valores de Inset como podría basarse en la orientación del dispositivo.

Código:

func setTableViewContentInset() { let contentInsetHeight = topLayoutGuide.length let contentInset = UIEdgeInsetsMake(contentInsetHeight, 0, 0, 0) tableView.contentInset = contentInset tableView.scrollIndicatorInsets = contentInset } func scrollToTop() { if tableView.indexPathsForVisibleRows?.count > 0 { let topIndexPath = NSIndexPath(forRow: 0, inSection: 0) tableView.scrollToRowAtIndexPath(topIndexPath, atScrollPosition: .Top, animated: false) } } func scrollToTopOfVisibleCells() { if let visibleIndexPaths = tableView.indexPathsForVisibleRows where tableView.indexPathsForVisibleRows?.count > 0 { let topMostVisibleIndexPath = visibleIndexPaths[0] tableView.scrollToRowAtIndexPath(topMostVisibleIndexPath, atScrollPosition: .Top, animated: false) } } //MARK: Load Views override func viewDidLoad() { super.viewDidLoad() setTableViewContentInset() } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) scrollToTop() } //MARK: Trait collection change override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) setTableViewContentInset() scrollToTopOfVisibleCells() }


Establezca la posición y de tableview a la altura de la barra de navegación más la altura de la barra de estado (permita que sea la height )

es decir,

height = 64; // height of navigation bar = 44(In portait), height of status bar = 20 tableView.frame = CGRectMake(tableView.frame.origin.x, height , tableView.frame.size.width, tableView.frame.size.height);

Si está utilizando la función autolayout, simplemente cambie la actualización de la restricción superior de tableView en lugar de cambiar el marco.

y también cambie viewController automaticallyAdjustsScrollViewInsets a NO

self.automaticallyAdjustsScrollViewInsets = NO;

Si está soportando diferentes marcos de actualización de orientación y contentInset a (52) porque la altura de la barra de navegación en modo horizontal es 32.

revisa esta Sample


Esto funciona tanto en modo apaisado como en modo vertical en iOS8:

- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CGRect rect = self.navigationController.navigationBar.frame; float y = -rect.origin.y; self.tableView.contentInset = UIEdgeInsetsMake(y ,0,0,0); }


La mayoría de las veces, las soluciones que introducen una constante mágica no se escalan, por ejemplo, si el siguiente iPhone introduce una altura de barra de navegación diferente tendremos que actualizar nuestro código.

Afortunadamente, Apple nos proporcionó formas más topLayoutGuide de superar este problema, por ejemplo topLayoutGuide :

La propiedad topLayoutGuide entra en juego cuando un controlador de vista se encuentra en la parte delantera de la pantalla. Indica la mayor extensión vertical para el contenido que no desea que aparezca detrás de una barra de UIKit translúcida o transparente (como un estado o barra de navegación)

Programáticamente puede lograrlo con el siguiente fragmento de código (lo mismo se puede lograr a través de IB también):

override func viewDidLoad() { super.viewDidLoad() automaticallyAdjustsScrollViewInsets = false tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) }

Nota: topLayoutGuide está en desuso en iOS 11, en su lugar deberíamos usar la propiedad safeAreaLayoutGuide de UIView.


Mi caso ayudó a este (versión modificada del código de Bill Chan):

Versión Objetivo C:

- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CGRect rect = self.navigationController.navigationBar.frame; float y = rect.size.height + rect.origin.y; self.tableView.contentInset = UIEdgeInsetsMake(y, 0, 0, 0); }

El punto es que la tabla debe ser presionada hacia abajo para la altura de la rect.size.height de navegación ( rect.size.height ) más la altura de la barra de estado ( rect.origin.y );

Versión Swift (también compatible con Swift 2):

override func viewDidLayoutSubviews() { if let rect = self.navigationController?.navigationBar.frame { let y = rect.size.height + rect.origin.y self.tableView.contentInset = UIEdgeInsetsMake( y, 0, 0, 0) } }


Podría establecer el contenidoInset de su tableView para que esté inicialmente debajo de la barra de navegación, pero se desplazaría hacia atrás (el contenido se superpondrá)

self.tableView.contentInset = UIEdgeInsetsMake(44,0,0,0);

O podría compensar el marco de la tabla vista. Luego, el contenido desplazable se cortaría debajo de la barra de navegación (que tampoco se vería bien)


Restringe la vista de tabla a la parte inferior de la barra de navegación. La vista de tabla se compensará automáticamente por 44, pero luego en código podemos hacer esto:

tableView.contentInset = UIEdgeInsets(top: -44, left: 0, bottom: 0, right: 0)

La barra es transparente y no tiene color, pero la vista de tabla no se superpone en absoluto. Observe que la palabra "Hook" se corta a pesar de que la barra de navegación es transparente. Esto solo funcionará si restringe el borde superior de la vista de tabla a 0 desde la barra de navegación. NO 0 desde la vista superior.


Se me ocurrió la siguiente solución, que, al navegar por el controlador de vista por primera vez, ajusta el contenido de la vista de contentInset para la altura de la barra de navegación, teniendo en cuenta el relleno que pueda tener la celda superior. Al volver a este controlador de vista después de empujar otro controlador de vista en la pila, entonces reajuste el contentInset a UIEdgeInsetsZero :

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self adjustEdgeInsetsForTableView]; } - (void)adjustEdgeInsetsForTableView { if(self.isMovingToParentViewController) { self.tableViewForm.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height + padding, 0, 0, 0); } else { self.tableViewForm.contentInset = UIEdgeInsetsZero; } }


Solo este código resuelve el problema:

@IBOutlet weak var tableView: UITableView! func viewDidLoad() { super.viewDidLoad() self.tableView.contentInset = UIEdgeInsetsZero }


Tuve el problema similar para iOS 9. Cuando abro viewController por primera vez, tableView está debajo de la barra superior. Después de desplazarse por tableView todo funciona bien.

  1. Seleccione su controlador de vista
  2. Haga clic en la pestaña ''Inspector de atributos''
  3. Desmarque ''Under Top Bars''