How do I hide the top bar in UITabBarController using OBJ-C code (without using Interface Builder) ?
Please see the image in the link below to better understand my requirement.
http://skitch.com/jugsvn/dxkr7/iphone-simulator
I already have another toolbar as you can see and I don't want this. I'm not using XIB / NIB files and creating all the objects using plain OBJ-C code.
Cheers
Jugs
The topBar is part of the UINavigationController not the UITabBarController, you can hide it by putting the following in your viewWillAppear method:
self.navigationController.navigationBarHidden = YES;
But I'm pretty sure the navigationBar is always on top, so I think the bar you want to hide is actually your own toolbar.
self.myToolBar.hidden = YES;
self.tabBarController?.navigationController?.navigationBar.hidden = true
Related
I've made hundreds of table view controllers over the last decade and I don't know why this is happening. The content of my UITableView is stuck under my UINavigationBar (with a background color) in my UINavigationController. I was having this problem in an existing project, but to try to figure out the problem I created a fresh new project with nothing else in it.
I created a project.
Created TestTableViewController class that just adds some example sections/rows.
Removed the initial view controller from the storyboard.
Added a UITableViewController and set its class type to be TestTableViewController.
set UITableView's background color to UIColor.systemGroupedBackgroundColor.
Change the UITableViewCell to be Basic type and set its cell reuse id to be "Cell".
Told the storyboard to embed the TestTableViewController in a UINavigationController.
Set that UINavigationController as the Initial View Controller.
When I start the app, the navigation bar is hidden (I believe due to the scrollEdgeAppearance) and when I start to scroll away from the top edge, the nav bar starts to show up.
But I need a background color on my nav bar, so:
In the storyboard, I changed the UINavigationController's nav bar to have a background color.
Now the UITableView content is stuck under the nav bar.
I tried configuring the appearance of the UINavBar in my app delegate:
// in AppDelegate -didFinishLaunchingWithOptions
if (#available(iOS 15.0, *)) {
UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
[appearance configureWithOpaqueBackground];
appearance.backgroundColor = [UIColor systemRedColor];
UINavigationBar.appearance.standardAppearance = appearance;
UINavigationBar.appearance.compactAppearance = appearance;
UINavigationBar.appearance.scrollEdgeAppearance = appearance;
UINavigationBar.appearance.compactScrollEdgeAppearance = appearance;
}
But that didn't change anything. Next:
I tried creating a subclass of UINavigationController called TestNavController
Updated the storyboard to set the class on the nav to be TestNavController
Adding code to -awakeFromNib and -viewDidLoad to explicitly set the style on the nav bar:
// TestNavController, -awakeFromNib
if (#available(iOS 15.0, *)) {
UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
[appearance configureWithOpaqueBackground];
appearance.backgroundColor = [UIColor systemBlueColor];
self.navigationBar.standardAppearance = appearance;
self.navigationBar.compactAppearance = appearance;
self.navigationBar.scrollEdgeAppearance = appearance;
self.navigationBar.compactScrollEdgeAppearance = appearance;
}
The content is still stuck under the nav bar. Next I tried to take the storyboard out of the equation and in SceneDelegate.m in -scene:willConnectToSession:options, I swapped out the storyboard created root view controller with an entirely code-based root view controller:
TestTableViewController *testvc = [[TestTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
testvc.view.backgroundColor = UIColor.systemGroupedBackgroundColor;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:testvc];
self.window.rootViewController = nav;
and it works exactly as expected! So, why are my storyboard configured viewcontrollers and code-base appearance settings showing the wrong thing, while the code-based viewcontrollers look as expected? I've been using different colors in the various locations so that I can tell which code is the one having the effect. Red is being set in the App Delegate, Blue is being set in the TestTableViewController's awakeFromNib on the navigationItem.
I thought this was a problem with the scrollEdgeAppearance, but I've tried setting it via code and nothing seems to work.
Why is my content stuck under the nav bar when I use the storyboard? What am I missing?
Here is a link to download the project:
https://inadaydevelopment.com/stackoverflow/wtf.zip
It's a little hard to say whether this is a bug in the storyboard or not; it might be, and you should probably wrap this up into a nicer example and send it to Apple with a bug report. You should provide two projects, one that does everything in code and the other that does as much as possible in the storyboard.
One thing I can tell you is that I don't see Apple using the Grouped style of table with a section zero header. (Settings app is good place to look.) If you suppress your section zero header by setting the title to nil, things look fine because there is no title text getting stuck under the navigation bar.
If you're going to give the zero section a title when using a grouped style, you're probably going to want to compensate by giving the table section header some padding. That will keep it out from underneath the navigation bar. However, I ended up with zero padding after making some other changes.
Another issue I noticed is that it seems to matter what the footer height is. I got a much better look from your storyboard-based project by deliberately setting the footer height to 1 (it wouldn't let me set it to zero). In the end I wound up setting it to 10.
Plus I think you should set the header and footer estimated heights to 0 rather than leaving them at Automatic.
By playing around with all those parameters in my own project, I was able to get this, which looks to me a lot like your code-based example (except that I made the cells yellow so as to see clearly where they are):
Here are the size settings I ended up with (but you should tweak them more until you're happy):
And that's with
self.tableView.sectionHeaderTopPadding = 0;
This may help...
I took a look at your project and made one change.
Your table view in Storyboard has these settings:
and when I run the app I get this:
Changing only the Sections Header Height and Footer Heights to Automatic:
and I get this:
I created two projects from scratch - one loading the controllers from a Storyboard and one loading via code only - and wrapped everything up into a GitHub repo here: https://github.com/DonMag/wtfTable
Running either wtfSB or wtfNoSB gives me almost identical results (except for the default table background color and slight difference in section header heights):
The Apple guy in the What's new in Cocoa Touch WWDC video said that the new large-title navigation bar will magically hook into the top-level scroll view of the underlying view controller and collapse/expand itself automatically while scrolling up and down. (And by "magically", he probably meant that they failed to monkey patch this functionality into the already embarassing UINavigationController-UINavigationBar-UINavigationitem APIs in a usable way, so they had to resort to hooking into some heuristically chosen scroll view behind the scenes)
Even though I was prepared that this "automatic" collapse/expand wouldn't work if I deviate the slightest from the basic UINavigationController + UITableView/UICollectionView setup, it seems that even in this simplest case it doesn't work as expected.
Here's what I have:
A UITabBarController which contains a UINavigationController, which contains a UIViewController, which has a UITableView as its view. Tapping the first cell in the table will push a second view controller on the navigation stack:
No code, just the storyboard.
I've checked "Prefers large titles" for the navigation bar to activate large titles. Now, if I run the app and scroll up/down on the table view, the navigation bar stays the same - large - size; it doesn't collapse:
However, I've found that if I set the second view controller's navigation item to use the small navigation bar (by setting "Large Title" to the value "Never"), then if I open that page and navigate back, the interactive collapse magically starts working on the first page:
Am I missing something here, or is this feature not working properly? Here's the sample project I'm using: https://github.com/tzahola/iOS-11-Large-Title-Navigation-Bar
And by the way, I'm using the officially released iOS 11, not the betas.
2017-09-23 Update: I've sent a bug report to Apple, and opened a ticket on openradar.me: http://www.openradar.me/radar?id=5017601935671296
If there is any other view in addition to tableView, also make sure tableView is on the top of that view(s), right under the Safe Area:
Good news! I've just figured out that if I set "Large Titles" to "Never" on the storyboard, and then set it via code, then it works:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;
}
Seems like Apple forgot to handle the case when the navigation item has its largeTitleDisplayMode set via the Interface Builder.
So until they fix this issue, leave "Large Titles" as "Never" on storyboards, and set them via code in viewDidLoad.
You just need to do that to the first view controller. Subsequent view controllers honor the value in storyboard.
Or instead of changing anything in storyboard, do this:
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 11.0, *) {
self.navigationItem.largeTitleDisplayMode = .never
self.navigationItem.largeTitleDisplayMode = .always
}
}
No matter which language!
This is because large titles on navigation item decides whether or not to collapse on the basis of large title behaviour on previous screen navigation item title.
Make sure that addSubview(tableView) placed before others addSuview(someview)
Year 2020, iOS 13.0, this WAS NEVER mentioned here. I literally spent an hour or two for this.
Issue: Large title won't collapse when doing layout programmatically using Snapkit (an autolayout framework)
Solution: SETUP YOUR VIEWS (including navigationController stuff and tableView) inside loadView() NOT in viewDidLoad().
#TamasZahola #mohamede1945
Guys I had the same problem. I was able to resolve this issue by adding following snippet on my first View Controller of Navigation Controller
navigationController?.navigationBar.prefersLargeTitles = true
It's an odd bug. The fix is to toggle OFF prefersLargeTitles in the storyboard and to set this in viewDidLoad of your nav controller's root vc:
navigationController?.navigationBar.prefersLargeTitles = true
TableView of its container should be at the top of ViewController's view hierarchy (RootView on screenshot). Otherwise it won't work.
I have a NavigationController and I want to make a View that animates itself from the top of the screen and sits above navigationBar. I'm initialising viewcontroller from a xib and it works perfectly when I add it as [self.view addSubview:myView]; , but it sits below navigation bar. When I try to add it as [self.navigationController.view addSubview:myView]; it places it on top of navigationBar as intended but view doesn't display any of it's subviews placed in xib. I can't see why this is happening, have been trying to solve this for hours.
UPDATE
My custom view from a xib is paired with custom ViewController class and I added this code in it :
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"!!! %i", [self.view.subviews count]);
}
if I add myView to self.view it prints 1 (there's actually 1 subview), but when I add it as self.navigationController.view -viewDidAppear is not even called. But it does appear on the screen with no subviews. Now I'm even more confused.
I think you need use this:
[self.navigationController.navigationBar addSubview:myView];
Why don't you just remove the navigation controller if you don't need it? Another way is to hide the navigation bar so that view occupies complete space and then show the navigation bar again when needed.
I could help more if you provide some code with the views.
Turns out I'm an idiot. It's a really simple scope problem. I was instantiating a local variable of my VC inside the method, and of course it was released at the end. As soon as I assigned my VC to a global variable all started to work like a charm. Easy as that.
I want to add a subview (a segment control) like Viber app main screen.
I tried setting self.navigationItem.titleView = myCustomView, but it seems to not working
How can I achieve my goal?
If you are adding this code from a UIViewController inside a UINavigationController, this code should work. So You need to check some points:
This view controller is part of the navigation controller?
The navigation bar is part of the navigation controller?
Are you initializing myCustomView correctly? Is it non-nil when you do this?
Is this view controller in the top of the stack? As written in the docs, and you can see that according to what you see from apps in general, this titleView is only used when item is topmost on the stack.
Try to NSLog the following to check some of them:
NSLog(#"self.navigationItem exists? %d", self.navigationItem != nil);
NSLog(#"customView exists? %d", customView != nil);
I have a UINavigationController with a left and a right button on an app being used as a remote control for a piece of hardware. I would like to show that the hardware is connected to the app by displaying an icon in the navigation bar to the left of the right button. From the documentation it looks as though I can only add UIBarButtonItems which make me suspect there is another, more conventional place for my 'connected LED' indicator.
So my question is can I display an icon in a UINavigationController navigation bar and if not where should I display it?
UINavigationBar is a subclass of UIView, so you can add items to it like this:
[navBar addSubview:whatever];
The navigation bar is a property of the navigation controller (i.e. you can reference it like this self.navigationController.navigationBar).
There isn't really a "conventional place" for something like this. :)
I suspect this 'connected LED' should be displayed on all views, regardless of the current view (and its UINavigationItem). If that is correct, the easiest way would probably be to NOT put that icon in the actual UINavigationBar, but place it as a separate UIView in the UINavigationBar's superview.
you should be able to just create a uiview programatically and add it as a subview of the navbar
UIImageView *connectedView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"connected-icon.png"]];
[self.navigationController.navigationBar insertSubview:connectedView atIndex:0];
[connectedView release];
if insertSubview doesn't work as you expect try addSubview:
[self.navigationController.navigationBar addSubview:connectedView];
You probably want to create the connectedView as a property though so you can (more) easily remove it when you are no longer "connected".
see this other examples of the approach
try this code
[[[yourViewController viewControllers] lastObject] navigationItem].titleView = yourImageView;
worke for me in customising navigation bar in mail controller. Hope you get some idea from here.