UITableView controller removes custom NavBar TitleView - ios

I have a bit of code that allows me to customize the Navigation Bar title of a view to allow for shrinking / truncating of long titles. The code works fine almost everywhere, however when it's used in a UITableViewController, the title never appears.
The code in question is:
- (void)viewDidLoad
{
[super viewDidLoad];
//Nav bar title for truncating longer titles
CGRect frame = CGRectMake(0, 0, 400, 44);
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:20.0];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.adjustsFontSizeToFitWidth = YES;
label.minimumFontSize = 10.0f;
label.lineBreakMode = UILineBreakModeTailTruncation;
label.text = #"This is a really long title. It will shrink and eventually get truncated correctly.";
self.navigationItem.titleView = label;
}
I've put together a small demo project that illustrates the problem.
https://sites.google.com/site/coffeestainit/files/NavTitleError.zip

I just went through your project. The problem is that in your storyboard, you have not connected your tableViewController to the FirstViewController. So the viewDidLoad of the
FirstViewController is never called.
When I set the custom class of your TableViewController to FirstViewController in the storyboard, it set the label as title, as expected

Related

Presenting UIAlertController increases UILabel font size inside UIToolbar in iOS 11

I have an issue with font size of UILabel, which is programmatically added in UIToolbar:
- (UILabel *)createTitleLabel
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(_topToolbar.frame)/3, CGRectGetHeight(_topToolbar.frame))];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithWhite:0.1 alpha:1.0];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont fontWithName:#"ArialMT" size:18];
label.adjustsFontSizeToFitWidth = YES;
label.minimumScaleFactor = 0.8;
label.lineBreakMode = NSLineBreakByTruncatingTail;
return label;
}
// -----
UILabel *label = [self createTitleLabel];
self.titleLabel = label;
[self.topToolbar insertItem:[[UIBarButtonItem alloc] initWithCustomView:label] atIndex:_topToolbar.items.count/2 animated:NO];
// ------ code for adding item to toolbar
- (void)insertItem:(UIBarItem *)barItem atIndex:(NSUInteger)index animated:(BOOL)animated
{
NSMutableArray *toolbarItems = [self.items mutableCopy];
NSAssert(index <= toolbarItems.count, #"Invalid index for toolbar item");
[toolbarItems insertObject:barItem atIndex:index];
[self setItems:toolbarItems animated:animated];
}
After setting a bit large text to title label, it works as expected, font is reduced, and tail is truncated, but when I present UIAlertController, this font is getting larger, and UILabel width is growing, which hides other bar button items inside toolbar.
Beginning with iOS 11, views added to toolbars as UIBarButtonItem using customView initializer are now laid out using auto layout. You should add sizing constraints on your label. For example:
[label.widthAnchor constraintEqualToConstant:CGRectGetWidth(_topToolbar.frame)/3].active = YES;
[label.heightAnchor constraintEqualToConstant:CGRectGetHeight(_topToolbar.frame)].active = YES;
Otherwise, auto layout will use the intrinsic content size of your label which is causing the label.adjustsFontSizeToFitWidth = YES; to be ignored. Sizing likely works initially because adding a bar button item doesn't trigger a layout pass, however presenting and dismissing another view controller will cause auto layout to perform a pass for your view controller's entire view hierarchy.
For more information see the WWDC 2017 session Updating your app for iOS 11.

objc - UITableView Title too wide.. What are my options?

I have a UITableView where I would like to set the tableView title to a wide label.
I'm trying to do something like:
"Daily Schedule - Long Station Name"
Ideally, this would mean a title and a subTitle. As there isn't a subtitle field, is there anyway to display a wide label?
Please note that I am not asking about UITableView Section Headers.
This is about the TableViewControllertitle.
Thanks
I think you are referring to the title displayed by the UINavigationController. In that case, you can get away with a custom title view, in which you can have two lines in the text label. Here is an example I'm currently using.
// Title label is the view we will assign to the titleView property
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 140, 50)];
titleLabel.numberOfLines = 2;
titleLabel.text = #"Daily Schedule - Long Station Name";
titleLabel.textColor = [UIColor whiteColor];
titleLabel.font = [UIFont fontWithName:#"Montserrat-Regular" size:22];
titleLabel.adjustsFontSizeToFitWidth = YES;
titleLabel.minimumScaleFactor = 0.8;
titleLabel.textAlignment = NSTextAlignmentCenter;
self.navigationItem.titleView = titleLabel;
Edit or delete the attributes to get the effects you want with your title.

Adjust font size in Navigation Title

Is there any way to make the font of the title of the navigation bar adjusted with the width?
Same behaviour as a [UILabel setAdjustsFontSizeToFitWidth:YES].
I'm trying setting the appearance of the NavigationBar, but no success so far.
Try doing something like:
self.navigationItem.titleView = titleLabel;
where titleLabel is a custom UILabel that you've initialized and customized.
Check out this Fontful code, for example.
There's no way to do this with the standard title item. You can still add your custom UILabel to the navigation bar and take care of the title changes.
You can not change the font of title.
Instead try out this..
self.title = #"My title is this.";
CGRect frame = CGRectMake(0, 0, [self.title sizeWithFont:[UIFont boldSystemFontOfSize:20.0]].width, 44);
UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.textAlignment = UITextAlignmentCenter;
self.navigationItem.titleView = label;
label.text = self.title;
[label release];

Want to change NavigationItem title

I've embedded my first view into a NavigationController and then i set the segue as push.
I want to change in each view the title of the Navigation bar to display something and update it through my code.
i tried to call the navigation controller like this:
self.navigationController.navigationBar.topItem.title = #"YourTitle";
but this wont work, how can I do it?
Navigation controller gets the title from the viewcontroller so
this will do the job
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Some Title";
}
This works for me:
self.navigationItem.title = #"YourTitle";
Hope it helps.
self.title = #"My Title"
This will change the navigation bars title as well as the title elements that refer to this view controller (eg. tab bar etc.)
self.navigationItem.title = #"My Title";
This will change only the title for the navigation bar for current view controller.
You can replace title view too:
UIView* titleView = [[UIView alloc] init];
[self.navigationItem setTitleView: titleView];
if u only change the navigation bar title then try this
on initwithnibname method
self.title=#"your title";
but you want to give a color or font size of title then u want to take a UIlable on it
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:20.0];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor blackColor];
self.navigationItem.titleView = label;
label.text =#"your title";
[label sizeToFit];

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;

Resources