ios uinavigationcontroller uinavigationbar ios11 navigationitem

iOS 11 navigationItem.titleView Ancho no establecido



uinavigationcontroller uinavigationbar (13)

Adición a las respuestas existentes:

Si su vista de título personalizada es una vista que ya tiene un tamaño de contenido intrínseco por defecto (que no sea .zero ), por ejemplo, un UILabel , un UITextView o un UIButton , simplemente puede configurar

yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false

y se ajustará automáticamente para encerrar su contenido, pero nunca se superpondrá con las vistas de elementos izquierdo y derecho.

Por ejemplo, puede arrastrar un botón al área de vista de título de una barra de navegación en Interface Builder, crear un titleButton de titleButton salida en su controlador de vista y luego hacer

override func viewDidLoad() { super.viewDidLoad() titleButton.translatesAutoresizingMaskIntoConstraints = false }

Ver un comportamiento en iOS11 con un navigationItem.titleView donde el ancho de titleView no es el ancho completo de la pantalla.

Tengo una vista personalizada que configuré como titleView. Antes de iOS11, la vista ocupaba el área de la barra de navegación. Pero iOS 11 no cambia el tamaño para llenar el ancho de la pantalla.

Intenté configurar el marco de la vista antes de configurar titleView, pero no tuve suerte. Intenté forzar la supervista titleViews a restricciones de diseño también, pero no tuve suerte.

Capturas de pantalla adjuntas:

iOS10:

iOS11:

¿Alguien más experimenta esto?


Cuando tiene una UIView como subvista dentro de CustomTitleView, la solución intrinsicContentSize no funciona, solo para mí en XCODE 9 en iOS 11. así que me gustó a continuación, funciona bien para mí, podría ayudar a alguien.

@interface CustomTitleView : UIView @property (weak, nonatomic) IBOutlet UIView *doubleTitleView; @end @implementation CustomTitleView - (void)awakeFromNib { [super awakeFromNib]; int width = _doubleTitleView.frame.size.width; int height = _doubleTitleView.frame.size.height; if (width != 0 && height != 0) { NSLayoutConstraint *widthConstraint = [_doubleTitleView.widthAnchor constraintEqualToConstant:width]; NSLayoutConstraint *heightConstraint = [_doubleTitleView.heightAnchor constraintEqualToConstant:height]; [_doubleTitleView addConstraint:heightConstraint]; [_doubleTitleView addConstraint:widthConstraint]; [heightConstraint setActive:TRUE]; [widthConstraint setActive:TRUE]; } }


Lo más importante es que necesita sobrescribir customTitleView como titleView:

self.navigationItem.titleView = [self titleView];

#pragma mark - getter - (UIView *)titleView { UIView *navTitleView = [HFCalenderTitleView new]; navTitleView.frame = CGRectMake(0.0, 0.0, HorizontalFrom750(200.0), 44.0); [navTitleView addSubview:self.titleLabel]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(navTitleView); }]; CGFloat btnWidth = 30.0; [navTitleView addSubview:self.previousButton]; self.previousButton.imageEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 15.0); [self.previousButton mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(navTitleView); make.top.bottom.equalTo(navTitleView); make.width.equalTo(@(btnWidth)); }]; [navTitleView addSubview:self.nextBtn]; self.nextBtn.imageEdgeInsets = UIEdgeInsetsMake(0.0, 15.0, 0.0, 0.0); [self.nextBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(navTitleView); make.top.bottom.equalTo(navTitleView); make.width.equalTo(@(btnWidth)); }]; return navTitleView; } #pragma mark - customTitleView #import "HFCalenderTitleView.h" @implementation HFCalenderTitleView - (CGSize)intrinsicContentSize{ return CGSizeMake(HorizontalFrom750(200.0), 40); // the target size }


Lo solucionó creando una subclase de UIView y lo asignó a una vista de título de UINavigationController

C objetivo:

#import "FLWCustomTitleView.h" @implementation FLWCustomTitleView - (CGSize )intrinsicContentSize { return UILayoutFittingExpandedSize; } @end


Me lo imaginé. Tuve que anular el captador intrinsicContentSize para la vista y el campo de texto.

Establecí el ancho en CGFloat.greatestFiniteMagnitude para que siempre sea tan ancho como la pantalla.

Actualizar:

Como he pasado un par de horas en este tema, espero que alguien más se ponga al día más rápido al tener todas las cosas juntas

He creado una subclase personalizada de TitleView , llamada CustomTitleView , aquí está el código:

import UIKit class CustomTitleView: UIView { override var intrinsicContentSize: CGSize { return UIView.layoutFittingExpandedSize } }

y la parte más importante que me perdí desde el principio fue esta:


Swift 4.2 Versión de la respuesta de Yedy

let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 80, height: 30)) imageView.image = image imageView.widthAnchor.constraint(equalToConstant: 80).isActive = true imageView.heightAnchor.constraint(equalToConstant: 30).isActive = true imageView.contentMode = .scaleAspectFit navigationItem.titleView = imageView

Convertido con la ayuda de Swiftify .


También puede usar restricciones si no desea anular intrinsicContentSize . Aquí hay una demostración de SnapKit

self.navigationItem.titleView = titleView if #available(iOS 11, *) { titleView.snp.makeConstraints({ (make) in make.width.equalTo(250) // fixed width make.height.equalTo(30) // less than 44(height of naviagtion bar) }) }else { titleView.frame = ... }

Pero si hay más de un elemento de barra de navegación en cualquier barra de navegación lateral (izquierda o derecha), debe usar intrinsicContentSize;


Tuve el mismo problema pero al configurar un UIImage como el elemento de navigationItem titleView

Lo que hice es escalar la imagen al tamaño necesario usando lo siguiente:

-(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }

Y llámalo como sigue:

-(void)setHeaderImage{ UIImage * image = [self imageWithImage:[UIImage imageNamed:@"headerImage"] scaledToSize:CGSizeMake(150, 27)]; UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.frame = CGRectMake(0, 0, 150, 27); imageView.contentMode = UIViewContentModeScaleAspectFit; self.navigationItem.titleView = imageView; }


Tuve que ajustar un UIImageView como navigationItem.titleView. La relación de aspecto se ajustaba pero el tamaño intrínseco del contenido lo hizo demasiado grande. Escalar la imagen condujo a una mala calidad de imagen. Establecer anclajes de diseño funcionó para mí:

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 30)]; [imageView setImage:image]; [imageView.widthAnchor constraintEqualToConstant:80].active = YES; [imageView.heightAnchor constraintEqualToConstant:30].active = YES; [imageView setContentMode:UIViewContentModeScaleAspectFit]; self.navigationItem.titleView = imageView;


Usando la respuesta de @ falkon, aquí está el código:

Agregue este código a la vista que se usa como titleView

override var intrinsicContentSize: CGSize { return UILayoutFittingExpandedSize }


establecer intrinsicContentSize en UILayoutFittingExpandedSize funciona bien


return UILayoutFittingExpandedSize no me ayudó, porque la vista se agregó verticalmente unas pocas veces más para completar el diseño.

La solución fue anular intrinsicContentSize en el ancho de configuración de vista personalizada al ancho máximo de pantalla:

- (CGSize)intrinsicContentSize { //fills empty space. View will be resized to be smaller, but if it is too small - then it stays too small CGRect frame = self.frame; frame.size.width = MAX(SCREEN_WIDTH, SCREEN_HEIGHT); return frame.size; }


Intente usar el estándar UISearchBar / UISearchController

En realidad, lo que debe hacer: si puede usar un UISearchBar estándar / un UISearchController, debe mostrar la barra de búsqueda de la siguiente manera que respeta el área segura y, por lo tanto, se ve perfecta en el iPhone X y en la orientación de cada dispositivo:

func presentSearchController() { let searchController = UISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.obscuresBackgroundDuringPresentation = false searchController.searchBar.text = "any text" if #available(iOS 11.0, *) { self.navigationItem.searchController = searchController searchController.isActive = true } else { present(searchController, animated: true, completion: nil) } }

Referencias

https://developer.apple.com/videos/play/fall2017/201/ https://medium.com/@PavelGnatyuk/large-title-and-search-in-ios-11-514d5e020cee