web-dev-qa-db-fra.com

uINavigationBar TitleView personnalisé par iOS se déplace lors de l'application d'un nouveau contrôleur de vue

J'utilise une vue de titre personnalisée pour un UINavigationBar avec le code suivant:

// 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;

Le problème est que lors de la présentation d'un nouveau contrôleur de vue, puis de son retour au contrôleur de vue d'origine, cette vue personnalisée se décale puis se recentre d'elle-même. S'il vous plaît voir la vidéo pour une démonstration de cela.

Veuillez regarder la vidéo ici: https://www.youtube.com/watch?v=961CCVQmpJM&feature=youtu.be

J'ai désactivé le redimensionnement automatique de chaque sous-vue du contrôleur de navigation avec le storyboard et en code pour chaque contrôleur de vue:

    // Set the navigation bar hidded on the log in view
    UINavigationController* mainViewController = (UINavigationController*)self.appDelegate.window.rootViewController;
    [mainViewController setNavigationBarHidden:YES];
    [[mainViewController navigationBar] setAutoresizesSubviews:NO];

Cependant, il redimensionne encore! Comment puis-je arrêter ceci - qu'est-ce que je fais mal? Merci!

24
PhilBot

Il ne peut être reproduit que si je place le paramètre titleView code dans viewWillAppear . Le déplacer vers viewDidLoad corrige le problème

33
Alex Peda

Je voudrais intégrer l'étiquette à l'intérieur d'une UIView. Interface Builder n'aime pas mettre directement une UILabel dans la titleView pour une raison quelconque qui pourrait être liée à votre problème.

Essayez également de définir autoResizingMask sur UIViewAutoresizingFlexibleTopMargin. D'après mon expérience, toute vue personnalisée dans les barres se comporte mieux de cette façon.

4
Rivera

C'est arrivé pour moi aussi. Deux choses que vous pourriez faire:

1) assurez-vous que la configuration de la navigation est effectuée dans viewDidLayoutSubviews ou viewDidLoad, comme indiqué dans la réponse ci-dessus 

2) J'avais le bouton de barre de gauche et de droite identique à zéro, mais je ne les ai appelés que lorsque l'étiquette du titre a été définie. Assurez-vous que les éléments des boutons des barres droite et gauche sont nuls (si vous ne les utilisez pas, bien sûr) avant de définir le label de titre sur titleview.

1
hellorrr

Ce qui a fonctionné pour moi a été de créer une variable dans le contrôleur de vue contenant la vue de titre souhaitée, puis de l’initialiser dans viewDidLoad. Ensuite, vous pouvez définir cette vue sur self.navigationItem.titleView dans viewWillAppear et elle devrait s'afficher correctement. Pas besoin de définir autoResizeMask, ni rightBarButtons, etc.

Exemple:

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
    }    
}
0
Alphonsus

Dans mon cas, c'est parce que je mettais UIBarButton avant titleView. TitleView devrait être le premier. Fonctionne parfaitement maintenant.

0
Michał Kwiecień

En développant la réponse de @Alex Peda ci-dessus, je constate que sur iOS7, en dehors de viewDidLoad, il semble y avoir une largeur de titre minimale pour un titre personnalisé. Voici ce que je fais, ci-dessous. Notez qu'il existe quelques méthodes ci-dessous spécifiques à mon code.

#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;
}
0
Chris Prince