iOS 7 Custom UINavigationBar TitleView se mueve al presionar o saltar el nuevo controlador de vista
iphone objective-c (6)
Estoy usando una vista de título personalizada para una barra de UINavigation con el siguiente código:
// Set a label to the nav bar
THLabel *titleLabel = [[THLabel alloc] init];
titleLabel.text = @"Test";
titleLabel.font = [UIFont fontWithName:APP_FONT size:22.0];
titleLabel.frame = CGRectMake(0, 0, 100, 30);
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.textColor = CUSTOM_LIGHT_BLUE;
titleLabel.strokeColor = kStrokeColor;
titleLabel.strokeSize = kStrokeSize;
self.navigationItem.titleView = titleLabel;
El problema es que cuando se presenta un nuevo controlador de vista y luego se regresa al controlador de vista original, esta vista personalizada se desplaza y luego se vuelve a centrar. Por favor vea el video para una demostración de eso.
Por favor vea el video aquí: https://www.youtube.com/watch?v=961CCVQmpJM&feature=youtu.be
He deshabilitado el ajuste automático de cada subvista para el controlador de navegación con el guión gráfico y el código para cada controlador de vista:
// Set the navigation bar hidded on the log in view
UINavigationController* mainViewController = (UINavigationController*)self.appDelegate.window.rootViewController;
[mainViewController setNavigationBarHidden:YES];
[[mainViewController navigationBar] setAutoresizesSubviews:NO];
Sin embargo, todavía se redimensiona! ¿Cómo puedo detener esto? ¿Qué estoy haciendo mal? ¡Gracias!
Ampliando la respuesta anterior de @Alex Peda, encuentro que en iOS7, fuera de viewDidLoad, parece haber un ancho de título mínimo para un título personalizado. Esto es lo que estoy haciendo, a continuación. Tenga en cuenta que hay algunos métodos a continuación de mi código.
#define MAX_TITLE_WIDTH 400
#define MIN_TITLE_WIDTH 150
- (void) setNavBarTitle: (NSString *) newTitle;
{
if (!newTitle) newTitle = @"";
NSMutableString *title = [newTitle mutableCopy];
if (![_titleView.text isEqualToString:title]) {
NSAttributedString *attrTitle = [UIAppearance attributedString:title withFontType:FontTypeTitle | FontTypeBold | FontTypeItalic size: 40.0 andOtherAttributes:@{NSForegroundColorAttributeName: [UIColor blackColor]}];
_titleView.attributedText = attrTitle;
[_titleView sizeToFit];
// In iOS7, if you set the nav bar title with a custom view outside of viewDidLoad, there appears to be a minimum title width. Narrower custom view titles are not centered properly. I''m working around this by centering the text in the label, and setting the width of the label to the minimum width.
if ([Utilities ios7OrLater]) {
if (_titleView.frameWidth < MIN_TITLE_WIDTH) {
_titleView.textAlignment = NSTextAlignmentCenter;
_titleView.frameWidth = MIN_TITLE_WIDTH;
}
}
if (_titleView.frameWidth > MAX_TITLE_WIDTH) {
_titleView.frameWidth = MAX_TITLE_WIDTH;
}
}
self.navigationItem.titleView = _titleView;
}
En mi caso sucedió porque estaba configurando UIBarButton antes de titleView. La configuración de titleView debería ser la primera. Funciona perfectamente ahora.
Es reproducible para mí solo si coloco la configuración del código de vista de título en viewWillAppear . Moverlo a viewDidLoad soluciona el problema
Esto me pasó a mí también. Dos cosas que podrías hacer:
1) asegúrese de que la configuración de navegación se realice en viewDidLayoutSubviews o viewDidLoad como se menciona en la respuesta anterior
2) Tenía el elemento del botón de la barra izquierda y derecha como nulo, pero solo los llamé después de que se estableció la etiqueta del título. asegúrese de configurar los elementos de los botones de la barra derecha e izquierda como nulos (si no los está utilizando, por supuesto) antes de configurar la etiqueta de título para titleview.
Lo que me funcionó fue crear una variable en el controlador de vista que contiene la vista del título que desea y luego inicializarla en viewDidLoad
. Luego, puede establecer esa vista en self.navigationItem.titleView
en viewWillAppear
y debería mostrarse correctamente. No es necesario configurar autoResizeMask, o rightBarButtons, etc.
Ejemplo:
class ViewController {
var myTitleImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
myTitleImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
myTitleImage.contentMode = .scaleAspectFit
myTitleImage.image = #imageLiteral(resourceName: "my_title_image")
// etc...
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.titleView = self.myTitleImage
}
}
Yo incrustaría la etiqueta dentro de un UIView
. A Interface Builder no le gusta poner directamente una UILabel
en el titleView
por alguna razón que pueda estar relacionada con su problema.
También intente establecer la función autoResizingMask
de UIViewAutoresizingFlexibleTopMargin
en UIViewAutoresizingFlexibleTopMargin
. En mi experiencia, cualquier vista personalizada en bares se comporta mejor de esta manera.