Title text hugging/kerning + clipping in UITabBarItem - ios

I have a UITabBarController like this:
As you can see, the 'Discover' and 'Requests' titles are compressed by high amounts of kerning. They are also slightly clipped at the end of each item title. Is there any way to fix this?
P.S. The problem does not appear on iPhone 6 and 6+, only 5S and below.

It seems like there is an issue with UITabBars where, if they deem their frame too small, they'll attempt to kern the item title labels to fit.
This issue with frame size can happen either from manually setting the frame of the UITabBar or possibly by having a larger number of items than will comfortably fit on screen (in your case 5).
In my experience with this issue, someone had erroneously set the frame of the UITabBar to CGRectZero so that, while hidden, it wouldn't effect layout geometry for a UIToolbar. Might you be manually editing the frame of one of the two tab bars you have?

I had this issue happen when I was trying to add a UITabBarController too soon. I was adding it as a child view controller of the main window.rootViewController in its viewDidLoad: method. However, the root view has not been properly initialized at this point yet, so the tab bar was using incorrect frame for calculations (as Ben Lachman alluded to). I solved it by adding a delay to initialize the images on the tab bar items, which in turn made the titles display with correct spacing.

Related

iOS 12 wrong navigation bar height

I'm working on an iPad app in landscape orientation. There is a navigation bar at the top without a status bar, and I want to line up a UITableView such that the top of the table is at the same y coordinate as the bottom of the navigation bar. Naturally, I do the following in viewDidLoad:
MyTableView* table = [[MyTableView alloc] init];
table.frame = CGRectMake(someX, navBar.frame.size.height, someWidth, someHeight);
[self.view addSubview:table];
At this point, navBar.frame.size.height returns 44. This is strange, because when I run the app, I see that my table overlaps the bottom of the navigation bar by a few points. I do some investigation, and find out that the navigation bar is actually drawing with a height of 50 points.
I try to think what could be wrong, and realize that perhaps I'm doing this too early in the view controller's lifecycle and the views haven't yet been laid out, so I override viewWillAppear, viewDidAppear, and viewDidLayoutSubviews, all of which report that the navigation bar's height is 44, even when it is clearly drawing with a height of 50.
I thought perhaps there's something I simply don't know, so I setup a timer to run a block of code that would repeatedly print out the height of the navigation bar every second after viewDidLoad was called, which allows for any view controller behind-the-scenes setup to finish. Still, every time the timer triggers the print, the height is only 44.
I took a look at interface builder, and even there, in the dimensions property window (second tab from right), it says the navigation bar has a height of 44. Yet on the screen in the view controller in interface builder, it is clearly drawing with a height of 50.
My question is: why does the reported height not match the height the navigation bar draws at? I need the correct height to place my table in the right location.
At this point I'm at a loss for what could possibly be the issue, save for the API simply being completely broken. The only solution I can think of is to just position the navigation bar at -3 and hardcode in a y value for my table view of 44, resulting in 3 points on the top and bottom of the navigation bar being covered up, which is super janky and I want to avoid it if at all possible.
Now, I understand that autolayout is a thing and constraints exist, but I like to manually compute the frames of my views in code and never use constraints, and that is the realm that this question is in. Please don't give answers like "you're supposed to use constraints".
Although I doubt it matters, I'm running iOS 12.0.1 on an iPad Air 2.
My debugging:
Below is an image of the top center portion of my screen. Each of the rectangles is simply a UIView with a background color set, a y coordinate of 0, a width of 50 points, and are spaced 50 points apart from each other (each starts where the previous one ends). The heights of each rectangle from left to right are: 44, 50, and 51. You can tell the navigation bar is drawing at a height of 50 points since the right rectangle is just barely taller than the navigation bar.
EDIT:
I should probably mention that this navigation bar is added to the view controller via being dragged and dropped into a view controller in the storyboard. I still do some frame shenanigans in viewDidLoad, but it's not being dynamically added to the view there.
Another interesting thing of note: In interface builder, you know the dashed blue lines that help you line things up? Apparently, those align with the 44 point height instead of the 50 point height:
After too much time spent with no progress, I decided to finally bite the bullet and transition to constraints. After I spent far too much time trying to get them to do what I wanted (and failing), it turns out that manually laying out my views wasn't the issue. During the conversion process, I deleted my navigation bar and re-added it to the view controller, which caused everything to start working perfectly. The dashed blue alignment guides lined up with the 50 point height and the height field now always returns 50.
My guess is that the logic in Xcode to upgrade storyboards from pre iOS 12 navigation bars (44 points high) to the new iOS 12 navigation bars (50 points high) is broken, which put my storyboard into a bad state where it thought the height was 44 in some places and 50 in others. Deleting and re-adding it looks to have cleared any record of 44-ness so everything is now properly 50 points high.

Remove UISearchDisplayController translucent overlay prior to search

I'm working with a situation similar to the screenshot below (taken from another question asked about the gap at the top) .
I know how to make the UISearchDisplayController's tableView show up in whatever frame someone wanted, and that's great, but now I'm dealing with this black translucent overlay that I cannot get to move.
No amount of changing any frame for a tableView in any order is fixing it. The only thing that fixes it is changing EdgesForExtendedLayout property for the parent controller, and this is not an option given the way everything else on the page and application is displayed.
So, how can I remove or shift the translucent overlay to whatever Y position I want?

How to make a UITableViewController subclass respect topLayoutGuide in iOS7?

in my app I have a simple UITableViewController that's just plain Objective-C code, no .xib or storyboard involved. It represents the contents of one tab in a tab bar.
Since iOS 7 its contents are overlapped by the status bar at the top and tab bar at the bottom.
Using only code, how can I make the table view add space at the top and bottom to align with topLayoutGuide and bottomLayoutGuide?
I know about
self.edgesForExtendedLayout=UIRectEdgeNone;
but that seems to simply shrink the table view to not intersect the tab bar and to disable the transparency of the tab bar. Instead I'd like the table view to add some padding.
Thanks!
Update:
I've also tried explicitly setting automaticallyAdjustsScrollViewInsets to YES, but that didn't help either (should be the default behavior anyway).
It seems this is not (yet) supported, at least for programmatically created UITableViewControllers without an UINavigationController that's embedding them.
I checked the position for both layout guides, and at run-time both off-sets read 0 distance from the edges of the screen. Hence automaticallyAdjustsScrollViewInsets won't set the insets correctly.
So now I actually modify my first section header and last section footer manually to add 21 pixels at the top and 50 pixels at the bottom respectively.
Bummer. :-(

UISplitView with UITabbar

I have a strange one that I can not seem to fix. I am currently working on updating my app to iOS7. This all worked in iOS6. It is an universal app and thus uses same xib files. However the iPad uses UISplitViews on some. Like I said, this all worked in iOS6 oh this all works on the iPhone too.
The problem is a grey bar at the bottom. I changed the tab bar to be opaque to move views up properly as i had some UI clipped to bottom of views and that went underneath the tab bar, sidetracked there. But if i set it back to translucent bar, it goes underneath but stretched properly. if i dont, it adds a bar. Other tabs work fine when NOT using splitview.
The UISplitviewController is added programmatically.
See attached image for better description.
This I have tried:
Added autoresize on splitview
Checked xib for subviews in the splitviews to have auto resize
Tried to force splitview to be screen bounds
Removed clips to bounds on all views
Removed autoresize subviews
Any ideas would be welcomed.
Thank you all.
UPDATE:
setting the background colour the uisplitview, it does colour the bar black. So the uisplitview is definitely stretching to it.
I subclassed UISplitViewController and added the line below to viewDidLoad and that fixed the grey line.
self.extendedLayoutIncludesOpaqueBars = YES;
I believe I have found an alternative solution for you. I have had the exact same problem, mostly because we are both doing something against Apple's Guidelines which is having a SplitViewController nested within a Tabbar controller (SplitView should be the root view). This was okay in iOS 5/6, but now in iOS 7 there are far too many side effects to achieve this.
The reason you see your view stretch completely when you set the bar to be translucent is because the bar is NOT taken into account when drawing the view. When you set translucent to false, it is then taken into account of the view and you will see that grey bar there because that's your view pretending there's a tabbar at the bottom of the screen.
And as always, a SplitViewcontroller's height cannot be changed, as it is determined by the visible window height.
I tried everything you did and then some. The real solution came from using a third-party Split View Controller.
I recommend switching over to https://github.com/mattgemmell/MGSplitViewController . This split view controller is actually one large View with container views living inside of it. Because of this, you avoid all the side effects of putting an actual split view controller within a tab bar.
If that doesn't float your boat, you could create your own solution which follows the same idea of having one UIViewController with two container views contained in it, though the people behind MGSplitViewController did a good job of that already.
This was the only way I was able to solve this issue, let me know if you find an alternative.
Instead of creating a subclass for UISplitViewController, I just added this code on my master's viewDidLoad:
self.splitViewController?.extendedLayoutIncludesOpaqueBars = true
For the controller that is the detail view of UISplitViewController you just do this:
-(UITabBarController*)tabBarController{
return nil;
}

Simple Horizontal Button Bar for iOS

I have a requirement for a very simple Button Bar.
It should take up the width of the screen.
It should allow at least 3
buttons.
The buttons should be of equal width and together take up
the whole width of the bar.
Each button should be tappable, but not
have a selected state.
The bar will be overlaid on a MapView and positioned directly above a TabBar.
Tapping a button will launch a Modal ViewController.
I thought about using a UITabBar and not allowing its tabs to become selected, but the HIG is pretty clear that this is not correct usage and UIToolBar doesn't allow the button widths to be set.
This seems like a very simple requirement but I can't see an obvious solution. Is there something I'm missing? Can anyone suggest a solution?
What's wrong with just creating a simple view that draws an appropriate gradient, and then adding three buttons of the appropriate size?
If you're feeling ambitious, or if this is something that you're likely to use more than once, you could even have the view create the three buttons. Call it ThreeButtonBar or something. Give it a constant height and adjust the width to match that of its superview so that you can use it in portrait or landscape orientation.

Resources