UISearchBar aumenta la altura de la barra de navigation en iOS 11

Tengo mi UISearchBar como parte de la barra de navigation como:

  let searchBar = UISearchBar() //some more configuration to the search bar ..... navigationItem.titleView = searchBar 

Después de actualizar a iOS 11 algo raro pasó a la barra de búsqueda en mi aplicación. En iOS 10 y antes tenía mi barra de navigation como:

introduzca la descripción de la imagen aquí

Ahora con iOS 11 tengo:

introduzca la descripción de la imagen aquí

Como puede ver, hay una diferencia en el networkingondeo de las dos barras de búsqueda que no me molesta. El problema es que la barra de búsqueda aumenta la altura de la barra de navigation. Entonces, cuando voy a otro controller también se ve extraño:

introduzca la descripción de la imagen aquí

De hecho, la altura de la línea negra extraña más la altura de la barra de navigation actual es igual a la altura de la barra de navigation que se muestra en la segunda image …

¿Alguna idea de cómo deshacerse de la línea negra y tener una altura de barra de navigation consistente en todos los controlleres de vista?

Puede agregar una restricción de altura 44 a la barra de búsqueda para iOS 11.

 if #available(iOS 11.0, *) { searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true } 

Creo que en iOS 11 UISearchBar ahora tiene la altura igual a 56, y UINavigationBar utiliza la reproducción automática para ajustar sus subviews, por lo tanto, aumenta la altura. Si aún desea tener UISearchBar como titleView como en pre-iOS 11, descubrí que la mejor manera de hacerlo es incrustar UISearchBar en una vista personalizada y establecer el alto de esta vista en 44, y asignarlo a navigationItem.titleView

 class SearchBarContainerView: UIView { let searchBar: UISearchBar init(customSearchBar: UISearchBar) { searchBar = customSearchBar super.init(frame: CGRect.zero) addSubview(searchBar) } override convenience init(frame: CGRect) { self.init(customSearchBar: UISearchBar()) self.frame = frame } requinetworking init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() searchBar.frame = bounds } } class MyViewController: UIViewController { func setupNavigationBar() { let searchBar = UISearchBar() let searchBarContainer = SearchBarContainerView(customSearchBar: searchBar) searchBarContainer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44) navigationItem.titleView = searchBarContainer } } 

En mi caso, la altura más grande de UINavigationBar no fue un problema para mí. Solo necesitaba realinear los elementos del button de barra izquierda y derecha. Esa es la solución que he encontrado:

 - (void)iOS11FixNavigationItemsVerticalAlignment { [self.navigationController.navigationBar layoutIfNeeded]; NSString * currSysVer = [[UIDevice currentDevice] systemVersion]; if ([currSysVer compare:@"11" options:NSNumericSearch] != NSOrdenetworkingAscending) { UIView * navigationBarContentView; for (UIView * subview in [self.navigationController.navigationBar subviews]) { if ([subview isKindOfClass:NSClassFromString(@"_UINavigationBarContentView")]) { navigationBarContentView = subview; break; } } if (navigationBarContentView) { for (UIView * subview in [navigationBarContentView subviews]) { if (![subview isKindOfClass:NSClassFromString(@"_UIButtonBarStackView")]) continue; NSLayoutConstraint * topSpaceConstraint; NSLayoutConstraint * bottomSpaceConstraint; CGFloat topConstraintMultiplier = 1.0f; CGFloat bottomConstraintMultiplier = 1.0f; for (NSLayoutConstraint * constraint in navigationBarContentView.constraints) { if (constraint.firstItem == subview && constraint.firstAttribute == NSLayoutAttributeTop) { topSpaceConstraint = constraint; break; } if (constraint.secondItem == subview && constraint.secondAttribute == NSLayoutAttributeTop) { topConstraintMultiplier = -1.0f; topSpaceConstraint = constraint; break; } } for (NSLayoutConstraint * constraint in navigationBarContentView.constraints) { if (constraint.firstItem == subview && constraint.firstAttribute == NSLayoutAttributeBottom) { bottomSpaceConstraint = constraint; break; } if (constraint.secondItem == subview && constraint.secondAttribute == NSLayoutAttributeBottom) { bottomConstraintMultiplier = -1.0f; bottomSpaceConstraint = constraint; break; } } CGFloat contentViewHeight = navigationBarContentView.frame.size.height; CGFloat subviewHeight = subview.frame.size.height; topSpaceConstraint.constant = topConstraintMultiplier * (contentViewHeight - subviewHeight) / 2.0f; bottomSpaceConstraint.constant = bottomConstraintMultiplier * (contentViewHeight - subviewHeight) / 2.0f; } } } } 

Básicamente, buscamos vistas de stack que contienen elementos de button de barra y luego cambian los valores de las restricciones superior e inferior. Sí, es un truco de tierra, y no recomendará utilizarlo si puede solucionar su problema de cualquier otra manera.

EDITAR: La respuesta @zgjie es una solución mejor para este problema: https://stackoverflow.com/a/46356265/1713123

Parece que esto sucede porque en iOS 11 el valor de altura pnetworkingeterminado de SearchBar se cambió a 56, en lugar de 44 en versiones anteriores de iOS.

Por ahora, he aplicado esta solución alternativa, volviendo a establecer la altura searchBar en 44:

 let barFrame = searchController.searchBar.frame searchController.searchBar.frame = CGRect(x: 0, y: 0, width: barFrame.width, height: 44) 

Otra solución podría ser usar la nueva propiedad searchController en navigationItem en iOS 11 :

 navigationItem.searchController = searchController 

Pero de esta forma da searchBar aparece debajo del título de navigation.

En Objective-C

if (@available (iOS 11.0, *)) {[self.searchBar.heightAnchor constraintLessThanOrEqualToConstant: 44] .active = YES; }