How do I make my iOS7 UITableViewController NOT appear under the top status bar? - ios

My root controller is a TabBarController (tabbed application). One of the tabs, is a UITableViewController. When I switch to that and scroll through the items, they show up under the status bar at the top (signal, battery, etc). I don't want that. I want that to be opaque or... something. It's visually jarring with the text of the table cells underlapping the status stuff.
Can I fix this from my Storyboard with some attributes setting that I don't understand? Or do I need to add some methods to my subclasses? Or maybe I need to wrap my UITableViewController with some other kind of controller?
I've tried numerous variations of the ViewController Layout and Extend Edges settings in the Storyboard attributes page, but none of them seem to change it for the better.
Update: I think my problem is very similar to iOS 7: UITableView shows under status bar. The only difference, is that I'm embedded in a TabBarController, and that case is as the root view. I tried the solution listed there of embedding in a NavigationController and setting Show Navigation Bar to False, but it didn't make any difference.
Screen Shots:
My storyboard (shrunk) showing a tabbed controller, with 2 children, one single view, and the other the table view.
Settings for the tab bar controller
Settings for the table view controller
What the app ends up looking like on my phone
How the Story Ended
Despite lots of answers below, none of them really worked. Some kind of a little, but not really. I tried the Embed in NavigationController approach as well, and that also had issues. What did work though, was this:
Add UIViewController
Set child controller relationship with it and tab bar controller (just like the other two I already had)
Add a TableView (not controller) to the new UIViewController, position as desired, it'll snap to the bottom of the status bar
Set the TableView's delegate and tableSource as the new controller
Create a custom UIViewController subclass and update the class type of the controller in the storyboard
Copy the table related methods from my custom UITableViewController subclass to my new subclass
Select my prototype table cell from the original, and command+drag it to the new table view
Happily delete the original TableViewController (and wrapper NavigationController) too
Update the tab bar item to match the previous
Chock another one up for "you're trying to hard"

Try this in viewDidLoad:
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
20 px being the height of the status bar. If you have a navigation bar use 64 instead of 20

In case anyone is still reading this thread:
What worked for me is to also uncheck the "Extend Edges" options in the parent tab bar controller. That gives a consistent behaviour in iOS7 as well as iOS6.

I was having the same problem when using the SWRevealController.
Using the comments above and below I was able to get it to work by putting this in the
-(void)viewWillAppear instead of ViewDidLoad
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);

Have you tried adding something like this to the view controller's viewWillAppear method:
if ([self respondsToSelector:#selector(setEdgesForExtendedLayout:)])
{
self.edgesForExtendedLayout = UIRectEdgeNone;
}

In case anyone misses the How the story ended section at the end of the (now long) question, the short answer is: Use a simple UIViewController with a TableView, instead of a TableViewController if you want to achieve the stated goal.

I added the following to viewWillAppear
self.tableView.contentInset = UIEdgeInsetsMake(22, 0, 0, 0);

You can also solve this through Storyboard.
Select the Table View from the Project Outline (left side of the editor) and then go to Properties (right side) > Size inspector tab > Scroll View > Content Insets > Top

suppose your table's #IBOutlet is
#IBOutlet var tableView: UITableView!
create a function prepareTable(). add the below line into that method
tableView.contentInset.top = UIApplication.shared.statusBarFrame.height
call this method from ViewDidLoad()

Looks like you just want to make the NavBar nonTranslucent, you could try using
[self.navigationController.navigationBar setTranslucent:NO];

I encountered the same problem and the solution that worked for me was to add a section header view:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
I then added 20 to the origin.y of my text on the header.
I then changed the header height by adding 20 to the original height using the
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return myHeight+20;
}

For me an easy solution was (code is in C# that's because appears to be invalid)...
Just in the UITableViewController constructor create a new UIView (set same dimension of the TableView).
Add the TableView to the new created view.
Set new created View to the UITableViewController's View property...
On the constructor of the UITableViewController
var view = new UIView ();
view.Frame = this.TableView.Frame;
view.AddSubview (this.TableView);
this.View = view;

As of iOS 8.4 I didn't get anywhere with the various storyboard options listed in other answers.
I worked around this without resorting to any dimensional constants by putting a regular view in my tab controller, then filling that with a "Container View" which I then connected to my UITableViewController with an "embed" segue.
My table now respects both my navigation bar and the tab bar at the bottom.

Let's say your Outline view, or Storyboard, is a Tab Bar Controller that currently has a Table View Controller. When you run the app, your table view cells are running under the status bar that seems to have a transparent background. This sucks!
If you spent hours trying everything you could find on StackOverflow to no avail, felt like maybe it really was time to consider a new career and were preparing to dial 1-800-LUV-TRUK or 1-800-SHT-KIKR, give yourself a pat on the back, open up whatever elixir you drink in times such as this, because it's not your fault. Really. Travis is absolutely right that no amount of code in viewDidLoad, viewWillAppear, or viewDidAppear or button selecting/deselecting in IB will help in this situation.
Travis' solution above will certainly work, but it's a bit long, there's copying and pasting of code, I have a short attention span such that an episode of Bugs Bunny feels like a full-length movie to me, so I just know that I'll screw-up anything that complicated. But, hey, your mileage may, nay likely will, vary. Anyhoo...
In Xcode 7.3 for an app running iOS 9 (I assume 7 and 8 but I don't know this for certain and am currently too lazy to check) there is an easier way that doesn't require one to write any code. And it's done all within Xcode's Interface Builder.
(Caveat: Sorry if any of the terms aren't accurate. Please let me know where I was mistaken and I'll correct any mislabeling.)
Go to the Utilities area of Interface Builder and select the Object library from the library pane.
Select a Navigation View Controller object and drag it into your Storyboard scene. You'll notice that two scene items appear while you're dragging–these are a Navigation Controller Scene and a Table View Controller Scene.
Delete the duplicate Table View Controller Scene that came-along with your Navigation Controller Scene.
Select the relationship connection between your Tab Bar Controller and your Table View Controller and hit "Delete".
Reposition the Navigation Controller and your Table View Controller the way you want in your storyboard.
Control-drag from your Tab Bar Controller Scene to the Navigation Controller Scene and select "Relationship Segue, view controller".
Control-drag from your Navigation Controller Scene to your Table View Controller Scene and select "Relationship Segue, root view controller".
Lastly, in the Utilities' Objects library, drag a Navigation Item object into your Table View Controller Scene's Table View.
Now when you run your app, you will have a navigation bar and your table view cells will no longer appear under a transparent status bar.
Hope this helps.

Related

Can't link my UITableViewController to my nested UITableView

I need to provide some background to explain how I got to where I am. I'm trying to create an interaction that involves different segues (slide up from the bottom, slide in from right) and, as far as I can tell I can't mix these two styles amongst scenes that are embedded in a Navigation Controller because the Show segue will only appear from right to left if I do.
The behavior I want is: Initial View Controller -> Settings (segue from bottom) -> -> detail for selected Setting ('standard' segue from right to left)
I also want to put a navigation bar in the Settings view so I can have a Done button that will close the view (slide out of sight from top to bottom) like this:
Interface builder won't let me add a navigation bar when I'm using a Navigation Controller and without one it looks like this:
So, I tried something from a thread that suggested nesting views. It almost works (the first screenshot above was taken from that code), but it resulted in a new problem. That problem is that I can't link the nested `UITableViewController' to my SettingsTableViewController.swift custom class. It's simply not an option in the dropdown list of classes and so I can't configure my table of Settings options.
Here's the hierarchy I now have based on the suggestion from that thread:
Also, I've confirmed that my SettingsTableViewController.swift is subclassing UITableViewController.
I'm stumped and would really appreciate some help.
If you try this,
Add a UIViewController and a UINavigationController(this automatically comes with a UITableViewController.
For example sake, add a button to the UIViewController, right click and drag to the UINavigationController and setup the segue to the following show in the image.
Add another UIViewController and right click drag from the UITableViewController to the new UIViewController and use a push segue, which you can reference when you do 'didSelectRowAtIndexPath'.
You shouldn't need to connect things, because your UITableViewController is the rootViewController of a UINavigationController. If you use a UITableViewController the only thing you should have in it's hierarchy is the UITableView, if you want other things, you need to use a UIViewController and add a UITableView, but I don't think you need this because you can achieve your requirements with the default options.
Comment if this does not make sense, good luck,

Endless Controllers Cloning

I am newbie in iOS programming. I've been looking for this information couple days and I still don't have the best answer, so I ask you for help. Please don't comment it like "Search on google.." or so. I have already did this research.
I have an app with 2 Controllers on start. First is a ViewController and it's a simple TableView. Second one is a controller with navigation bar with two buttons on it - burger on the left and plus on the right. When burger is tapped, first ViewController (with TableView) is opened. This is all very simple, but there's a problem with that plus button - it should add a new controller, which is same as the second controller (same buttons, images, etc.) except 2 labels, that must be different. I don't know if the controller has to be ViewController or NavigationController because I want to have 2 custom buttons on navigation bar (burger, plus). I found something about ContainerView, but I'm not sure, if it's the right way.. I want to switch between controllers using slide gesture.
Problems:
every next controller has a "plus" button => it can make a new controller.
How to make all the controllers looks like the same.
I'm adding an image for better understanding: IMAGE
Looking at your image, a simple solution I will use is using UIScrollView, make paging enabled.
Put your tableView and first view controller at the first two pages, and make sure view controllers are all added to the main view controller's childViewController.
When plus button tapped, you expand your the scrollView, make the content size bigger, and add a new controller's view to the scrollView, and add the viewController to the mainViewController's childViewController, keep doing that when new view controller needs to be added, and remember to call 'setContentOffset' to scroll to the new page.
Because paging is enabled, you can swipe between pages with smooth animation that will stop at each page.
As for your problems, to make the same view controller and add new view controller when tap add button, that are the second step.
1. Create new view controller:
If you are using storyboard, you need to give the view controller an identifier, and initialize the view controller with:
UIViewControlller *viewController = [[UIStoryboard storyboardWithName:#"your_story_board_name"
bundle:nil] instantiateViewControllerWithIdentifier:#"you_vc_id"];
If you are using xib:
UIViewController *viewController = [[UIViewController alloc] initWithNibName:#"your_xib_file_name" bundle:nil]
If you are using code, just use the
[UIViewController new]
to create the viewController, they are created with the same source, they surely look the same.
2. To add the view controller the the next page:
Let's assume your are currently at the second page, that's the init state of your app, first page is the tableView.
If the bounds of your scrollView has size of screen size: size1, and every page has the same view size: size1, and when there are two pages, the content size is size2, we know
size2.width == size1.width * pages
at this point, the
size2.width == size1.width * 2
So, when a new page need to added, you need to increase the width of content size by size1.width, and set the new viewController.view's frame to
(CGRect){(CGPoint){size1.width * page, 0},size1}.
Make the add new page a common function, call it when the add button taps.
Hope it helps

Interface Builder : cannot assign custom class to table view controller

I am trying to create a simple app for iOS that uses a tab bar controller to present either a map view or a table view. Both the map view and the table view have the same navigation bar button items:
A Logout button on the left, and Refresh, Add New buttons on the right side of the navigation bar. So I have started experimenting the idea of having a parent controller called LocationViewController, which inherits from the UIViewController.
For the table view, I have a controller called TableViewController: LocationViewController, and another controller called MapViewController: LocationViewController.
On the storyboard, I added a set of two buttons (for refresh and add new) to the top header section of each view (very small, may be hard to see). See the image attached below:
There is no problem for me to assign the custom view controller MapViewController to my map view panel, but I cannot find the custom controller class TableViewController in the panel (see the below screenshot)
I found a similar post on stackoverflow, and a reboot solved that problem, which I also tried, but did not solve my problem at all.
You have added youe buttons in the wrong place. I do not know the right name for the bar, but it contains "associated objects". What you want to achieve should look something like this :
Unfortunatelly, you cannot add two UIBarButtonItems to one side of navigation bar via interface builder. You can either drag a UIView instead of UIBarButtonItem to that "slot" and add two UIButtons there, or you ca add multiple buttons from code.
Also, it seems that the name of your question is a bit misleading :) After carefull reread of your post I found the "right" question.
Answer - you have added a UITableViewController in your storyboard, but your class doesn't inherit from UITableViewController. If you want to keep the base class, you will have to make it a "plain" UIViewController and add a UITableView to it. Note, that this way you won't be able to have prototype cells.
You may need to subclass it from UITableViewController. Replace the UIViewController parent class for UITableViewController, like this:
class ViewController: UITableViewController {
Then make sure you selected the View Controller where blue color is all around it and then you can place the name of the class that inherits from UITableViewController.

How to place a button below a UITableView managed by UITableViewController

I have a screen with a table view managed by a controller based on UITableViewController. I would now like to affix a button to the bottom of the screen so that it does not scroll along with the table view cells.
Replacing the UITableViewController with a plain UIViewController is not an option, as I want to include a UIRefreshControl. From what I have read, using a UIRefreshControl without a UITableViewController is currently not possible without resorting to any hacks / relying on undocumented behaviour.
I tried using a UIToolbar provided by the navigation controller which my table view controller is contained in, but there are two problems with that approach:
I only want the toolbar with the button to be present in the top level table view. However, I have not found an elegant way to only show the toolbar for the top level table view. I want the toolbar to animate out of the screen to the left together with the table view when I drill down.
I have not found a way to increase the height of the toolbar. Would I have to put the button in a dummy UIView?
This is approximately what I am aiming for:
http://pic.rockmynews.com/img/free-iphone-app.png
Another idea is using a container view controller containing the button at the bottom and the table view controller above it as its child view controller. But that seems a lot of work for something this simple.
So what is the best way to do this? Any recommendations?
Create the UIView container view. But also create a UIViewController subclass to manage the container. Then, add your existing table view controller as a child view controller and add the table view as a subview. Now you can control all of the subviews and positions while still having automatic refresh control operation.
Just use
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
and return a UIView for the desired button. and
tableView:heightForFooterInSection
and return the footer height
If you aren't willing to use a container view controller, you could use a third-party pull to refresh control like https://github.com/samvermette/SVPullToRefresh instead. This has the added benefit of being backwards compatible with iOS 5, if you want to support it.
You can use a UITableViewController. Just override viewDidLoad and then resize the tableView to make room for your extra view and then add your view programmatically. Make sure to set the right resizing mask so that things look correct on different screen sizes. (Easily tested in the Simulator by trying it out on the iPhone4 and iPhone5)

iPhone : UINavigation Controller within a view displaying another view

I think I am having a case of disappearing up my own arse.
I am creating a small view on a ipad thats for settings (so not full scree), within this view. I need a navigation controller to show another view.
At the moment I have one class / xib
The xib contains the main view (graphic / boarder). This view is linked to the files owner and appear.
On the same xib, I also have a navigation controller that contains the inner view.
OnViewDidLoad I add the navigationcontroller.view to the subview and it appears. However I cant push anything off it. I wired up the delegate and etc but I am sure I am missing something stupid
Can I do this all within one controller / xib?
The only code I have done is
[self.view addSubview:mainNavigationController.view];
Is there some code I need to do for the navigationController
Just adding the navigation controller as a subview doesn't hook up the navigation controller to the view controller hierarchy properly. That's probably why it doesn't work.
Also the properties that need to be set are readonly properties, so I don't think there's anything you can really do about it.

Resources