Can't link my UITableViewController to my nested UITableView - 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,

Related

Passing through Segues, Determining what view the user is on and NavigationController buttons not appearing

Sorry for the long and possibly confusing question. In this I have 2 main problems with my code, those being: 1- When I embed my viewControllers in a UINavigationController and add a bar button item, nothing appears, yet it appears when I add it to the pageViewController. Secondly, I am wondering if there is a way to do this differently and use one button on the pageView (which appears on all viewcontrollers in it) and just determine what the user was looking at when they pressed the button and are taken to another viewcontroller.
I am trying to build a page-based application, and I have set up the application with 7 view controllers (One for each day of the week). I then have an AddViewController, where users can add data to a certain day. I was wondering if there is a way to only use 1 addView linked to the NavBar on the PageViewController, as when I embed all other viewControllers and add a bar button, it does not show up.
With the pageViewController being embedded, this is what it looks like with a bar button on it.
This then leads to:
Which works well, however I am wanting to pass data to various arrays (one for each viewController), and I want to know which ViewController the user wishes to add to (based off what day they were on). Is there a way to determine this and then unwind to the viewController and append the right data to the right array or should I have one addView per dayViewController? If that is the case, I am coming across the issue whereby the bar button items do not appear on the viewControllers when they are embedded in a navigationController. It looks like this:
StoryBoard: (Example: MondayViewController)
The outcome is a missing barButton: (Keep in mind I changed the tint Colour to white so it would be visible)
I was wondering if anyone has the answer to either of my problems, and once again, thanks for taking the time to look at this array of questions in one problem.
Any suggestions are welcome !
Rowan,
You can do this:
Create an UINavigationViewController and then embed an UIPageViewController in it.
In the data source for the UIPageViewController implement these two methods:
- pageViewController:viewControllerBeforeViewController:
- pageViewController:viewControllerAfterViewController:
Here you will return the correct instance of your DayViewController for each position (or nil if you are on the first/last page). Your data model would also be set here.
Add your "Add" bar button to the navigation bar of the UIPageViewController and let it push your AddViewController. When pushing the AddViewController provide to it the info on which day is currently visible. You will probably need to keep track of this your self. Use the - pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: method of the UIPageViewController delegate.

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.

Implementing A Mail app-like User Interface

I am trying to implement a user interface that is similar to the iPhone's Mail app.
The main screen displays a table. From the table the user can select a cell, at which point the next screen is launched. At the bottom, there is a bar showing a short text and an icon.
The second screen displays the details of the cell. It will also be a table display. The bottom bar shows icons associated to this screen.
What kind of layouts do I use to implement this in Xcode?
1. Do I use a View controller, add a View and embed a TableView and a Toolbar inside that view?
2. Do I use a Table View Controller and add a Table View inside it and use the bottom tool bar that comes with the table view?
In the Table View Programming Guide for iOS, under 'Recommendations for Creating and Configuring Table Views,' it says 'Use an instance of a subclass of UITableViewController to create and manage a table view.' When I use this, the bottom bar can only be fixed or disappear when going back and forth between two screens via segue. That makes me wonder whether I should just use a View controller which is against the recommendation.
Use a UIViewController
Why?
If you are going to display more than a tableView then it is recommended to use a UIViewController for the storyboard.
UIViewController are much more flexible. I guess your confusion comes from the following documentation line:
Use an instance of a subclass of UITableViewController to create and
manage a table view
This does not mean you must to drag and drop a UITableViewController on the storyboard. It means your class need to inherit from UITableViewController or at least implement the deleguate and datasource methods.
You would use UITableViewController only and only if you need to display a tableView.

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

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.

Using multiple copies of the same view controller in a storyboard

I have the following setup in my app:
My initial view controller is a UITabBarController.
the tabs:
1)UINavigationController->PostListVC
2)UINavigationController->CategoriesListVC
3)UINavigationController->PostListVC
4)UINavigationController->PostListVC
5)UINavigationController->MoreViewController
As you can see, 3 tabs contain the same viewController class, but should not contain the same view controller object - the view will display different information based on information he gets form the AppDelegate.
What I did is I created 5 UINavigationControllers, connected them to the uitabbarcontroller, then created a rootViewController segue for 3 of them to the same PostListVC View - that way I don't need to maintain 3 designs of the same view.
The problem that I get is that only the first PostListVC gets created properly ( the leftmost in the tab bar ) - the other tabs that point to a PostListVC just show a black screen.
I've tried to illustrate the way I wire-up the storyboard using a 3-tab example:
As you can see, both the upper-most and lower-most views are connected to PostListVC.
I do not know what the issue is. I assume I'm using storyboards somewhat wrongly.
Does anybody know how I can fix this?
Thanks!
EDIT:
I have created a simple, example project (Xcode 5) that illustartes this issue:
http://www.speedyshare.com/Srwfg/TabBarProblem.zip
EDIT 2:
A modified version of the example, showing the problem with the offered solution:
http://speedy.sh/JkdGC/TabBarProblem-2.zip
There is no way to create different tabBarItems with this method, and there's no way to place the barItems so that they're not in a row - even if you try to chagne the order of segues.
As you said you need three different instances of PostListVC then you should create three different viewcontrollers of type PostListVC and connect each tab to its own. The class is the same but each tab gets its own instance.
I have got your example program to work BUT I don't know if the solution will work for your full project. Hopefully, it will put you on the correct track.
The solution is to have ONE (1) Navigation Controller / embedded root view but TWO (2) segues from the Tab Bar Controller. Here's the picture:
It looks like there's a problem with multiple UINavigationControllers linking to the same UIViewController. But no problem with the same UINavigationController linking to the same UIViewController provided they are instantiated separately through the UITabBarController.

Resources