简体   繁体   中英

Why does navigationItem.titleView align left when presentmodalviewcontroller called?

I'm using a UILabel for the titleView of a navigation bar (I'm making simple in-app web browser). It works fine, except that when I present a modal view controller, the titleView shifts from the center of the navbar to the far left (underneath the back button). I've tested in 3.0 and up. Here is relevant code:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Title view label
    CGRect labelFrame = CGRectMake(0.0, 0.0, 120.0, 36.0); 
    UILabel *label = [[[UILabel alloc] initWithFrame:labelFrame] autorelease];
    label.font = [UIFont boldSystemFontOfSize:14];
    label.numberOfLines = 2;
    label.backgroundColor = [UIColor clearColor];
    label.textAlignment = UITextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    label.shadowColor = [UIColor blackColor];
    label.shadowOffset = CGSizeMake(0.0, -1.0);
    label.lineBreakMode = UILineBreakModeMiddleTruncation;
    self.navigationItem.titleView = label;
}

-(void)displayComposerSheet:(NSString*)mailto 
{
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    [self presentModalViewController:picker animated:YES];
    [picker release];
}

Screenshots: 在此输入图像描述

Any idea why this is happening? Thanks.

I looked into the problem with some hit and try and found the following facts:

  • If the UINavigationBar doesn't have the rightBarButtonItem, the titleView shifts towards the right by ~30pts.
  • It could be reproduced for leftBarButtonItem. But I haven't tried.

In a scenario where the a default UINavigationBar's (with no changes to rightBarButtonItem defaults) titleView is set. And then a new UIView is pushed to the navigation stack which HAS a rightBarButtonItem. Now, if this view is popped [with back button], the navigation bar will remove the rightBarButtonItem. And this will account for the weird offset that shifts the titleView towards a side.

How I fixed the problem was like this:

self.navigationItem.titleView = myCustomTitleView;

// Fake right button to align titleView properly.
UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:[[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 1)]];
// Width equivalent to system default Done button's (which appears on pushed view in my case).
rightBarButtonItem.enabled = NO;
self.navigationItem.rightBarButtonItem = rightBarButtonItem;

Everything is sweet now. yummmm.

Thanks to DougW for pointing me in right direction. Here's the best hack I found. Basically I retain the UILabel as a class property. Before presenting modal view I unset the titleView, and then reset it immediately after. When the modal view is dismissed I unset then reset the titleView. To the user none of this is visibly notable.

-(void)displayComposerSheet:(NSString*)mailto 
{
    self.navigationItem.titleView = nil;
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    picker.navigationBar.tintColor = [APPDELEGATE getNavTintColor];
    [picker setToRecipients:[NSArray arrayWithObject:mailto]];
    [self presentModalViewController:picker animated:YES];
    [picker release];
    self.navigationItem.titleView = titlelabel;
}

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
{   
    self.navigationItem.titleView = nil;
    self.navigationItem.titleView = titlelabel;
    [self dismissModalViewControllerAnimated:YES];
}

Does it animate? It may be animating the title view as though it's transitioning to a new view. I don't see anything wrong with your code as written.

I would suggest in your displayComposerSheet, you just unset the titleView, or animate the alpha of the titleView to 0.0. Then, animate it back to 1.0 when you dismiss the modal view controller. Not ideal, but it may look better that way.

Frankly, the whole UINavigation system is crap. We went ahead and re-wrote it ground up because of bizarre issues like these.

The only problem is your frame size. so u have to change it.

Try this one.

   UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 36.0)];

   label.font = [UIFont boldSystemFontOfSize:14];
   label.numberOfLines = 2;
   label.backgroundColor = [UIColor clearColor];
   label.textAlignment = UITextAlignmentCenter;
   label.textColor = [UIColor whiteColor];
   label.shadowColor = [UIColor blackColor];
   label.shadowOffset = CGSizeMake(0.0, -1.0);
   label.lineBreakMode = UILineBreakModeMiddleTruncation;
   label.text=@"Stack Overflow";  
   self.navigationItem.titleView = label;

You can try move the code in viewDidAppear :

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // You code to customize title view
    self.navigationItem.titleView = logoImage;
}

It works for me.

If you change the width size to be small like 100 points or smaller instead of 120 you set, this problem may go away. Setting width of the label smaller worked for me.

  UIView *view=    [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
  [view setUserInteractionEnabled:NO];
  view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"logo_small.png"]];
  UIBarButtonItem *barButton=[[UIBarButtonItem alloc]initWithCustomView:view ];
  self.navigationItem.leftBarButtonItem = barButton;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM