Create Relationship Segues - ios

How can I create a relationship segue? I would like to create a UIViewController subclass similar to UITabBarController or UINavigationController where, using Interface Builder, I can control + drag from a view controller to another view controller. I have tried
#property (nonatomic) IBOutlet NSArray *viewControllers;
#property (nonatomic) IBOutlet UIStoryboardSegue *root;
and also tried dragging a Container View into my view controller. When I do that, I can drag from one view controller to another but I cannot drag to more than one view controller. I also cannot find any documentation for a UIContainerView object.

Relationship Segues are handled by Interface Builder. You cannot create them manually if the starting view controller is not one of those you mentioned. The simplest solution for your issue is to create a TabBarController and hide its tab bar in code.
Here is a quite advanced tutorial on something very similar to what you are trying to do. You may get some more ideas from it. Advanced Storyboard Techniques
EDIT:
Thanks for the tip about using a TabBarController, but I am asking this question because I am trying to subclass UIPageViewController so that I can create the PageViewController's datasource from IB
That's an interesting idea, and here is an explained solution for that: Using UIPageViewController in storyboards You don't have to subclass the UIPageViewController, it is against the recommendation in the documentation, too. Create a class that implements the UIPageViewControllerDataSource delegate. Place a "green cube" in the page view controller's listing panel and set its class to be newly created one. Then drag from the datasource outlet to this cube.
However, the pages cannot be set up visually in this way or any other. It is unfortunately not supported at all.

Related

providing common functionality for different viewcontrollers in objective c

I have many viewcontrollers which needs to have some common functionality related to navigation.
Earlier I made a base class BaseViewController(extending UIViewController) which have all common functionality (like doing some tasks on viewDidLoad etc) and all my viewcontrollers extends BaseViewController.
The problem is that some of my viewcontroller should be subclass of UIViewController and some of UITableViewController, so I can not use above approach.
One way could be to write base class for both and duplicating code. Is there any better way without duplicating code.
While you can get around this by using delegation or helper objects, I would make the case for just not using UITableViewController. It is only a very light subclass on top of UIViewController, providing a table view, conforming to the delegate & data source protocols, and adding a property or two for selection & refresh.
While I wouldn't normally suggest recreating something that the framework has already done for you, it may (in your case) make your code more easy to understand if you just keep everything inheriting from a common base class and add a table view to one of the subclasses.
If you do think this would be a reasonable approach, the UITableViewController documentation overview gives a detailed description of exactly what & where these behaviours are implemented, so mimicking its exact setup is trivial.
Adding a table view to UIViewController
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#end
In your storyboard, drag a "Table View" from the object library and drop it on top of your View Controller scene's "View" in the Document Outline - this will replace the root view with a UITableView.
Then just hook it up:
ctrl-drag from the view controller to the table view to hook up the view and tableView outlets
ctrl-drag from the table view to the view controller to set the delegate and dataSource outlets.
Done - no magic required.

How do I resolve "Static table views are only valid when embedded in UITableViewController instances" when creating an app?

I am an Objective-C beginner and I am going through the tutorial to create an IOS app using Apple developer articles.
https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/SecondTutorial.html#//apple_ref/doc/uid/TP40011343-CH8-SW1
I have created an unwind segue and I have gotten stuck. I have gone through SO posts such as given below
StoryBoard issue in Xcode 6.1
Change a UIViewController to a UITableViewController inside a storyboard?
Want to create a cool static UI but : "Static table views are only valid..."
I tried to modify the story board source to use "tableViewController" instead of "viewController", but the storyboard won't open.
I am sure that there is an easy solution, but I don't know enough Objective-C or IOS development to know what it is, or how to implement it.
I have my controller implementing UITableViewController and my view as UITableView. I have attached the screenshot below.
and the error message:
My source for ToDoListTableViewController.h is given below:
#import <UIKit/UIKit.h>
#interface ToDoListTableViewController : UITableViewController
- (IBAction)unwindToList:(UIStoryboardSegue *)segue;
#end
and the implementation
#import "ToDoListTableViewController.h"
#interface ToDoListTableViewController ()
#end
#implementation ToDoListTableViewController
. . . Other methods
- (IBAction)unwindToList:(UIStoryboardSegue *)segue {
}
#end
Your picture is kind of small so it's a bit hard to tell what we're looking at. Plus your descriptions are a bit vague.
The deal is that in order to set up a table view as a static table view, it must be managed by a UITableViewController, not a regular UIViewController.
A UITableViewController is a special subclass of UIViewController. When you go to add a new scene to your storyboard, you go to the list of UI objects, find the UITableViewController, and drag one onto the storyboard.
An annoying thing about UITableViewController objects is that the ONLY thing they manage is a table view. You can't use them to set up labels, buttons, and other UI elements. Just a table view and nothing else.
You said:
'I tried to modify the story board source to use "tableViewController" instead of "viewController"...'
I have no idea what that means. What is a "story board source"? You don't "Modify the storyboard source", you drag a UITableViewController onto your storyboard.
Then you said "...but the storyboard won't open." I also don't know what that means. You're going to have to explain that.
Luckily, there is an easy solution to this.
What you want to do is to create a regular UIViewController to manage everything but the table view, and then put a "Container View" in that view controller and set up an "embed segue" that installs a UITableViewController inside that container view.
Here's how you do that:
Search in the list of UI elements on the right side for "container". Drag a container view onto your view controller where you want your table view to appear. Then drag a UITableViewController onto a blank space on your storyboard to create a new storyboard scene. Then control-drag from the container view in your first view controller onto the UITableViewController. This creates an embed segue, which causes the UITableViewController to be loaded as a child view controller with its view inside and sized to fit in the container view.
Now you can have a window that has both a table view managed by a UITableViewController AND other contents.
There are more details to setting this up that are beyond the scope of a SO post. I suggest you do some googling on container views and embed segues and try to find a tutorial on setting them up.

How can I connect one IBOutlet to an tableview controller in an container view controller

I have designed my app with Storyboard, I have one View controller and I need to insert a static table view controller (static table view controller can't insert into a view controller ). So I've drag&drop a container view controller and embed with a table view controller.
Now I have a IBOutlet declared in my viewcontroller.h, as
#property (nonatomic,strong) IBOutlet UITableView *infoTableView;
How can I connect the infoTableView to the actual table view in connections inspector?
If you mean connect an IBOutlet that's in ItemEditorViewController to the table view in the table view controller, you can't. It's not possible to connect an outlet in one controller to an object in another controller. If you need to get a reference to that table view in the parent controller, you need to do it code:
In ItemEditorViewController.h
#property (nonatomic,strong) UITableView *infoTableView;
In ItemEditorViewController.m (probably in viewDidLoad)
self.infoTableView = [self.childViewControllers[0] tableView];
It is not quite the answer you are looking for, but try not doing this sort of wanky stuff. Static tableViews are not allowed to be used in UIViewController for a purpose. Apple had his reasons to prohibit it, so you better not search for work-arounds, otherwise you will get a buggy app with unexpected behaviour. Do you really want that?
What I would suggest, as an idea for this situation:
Include a simple UITableView in your VC class, and just programmatically customise it in tableView:cellForRowAtIndexPath:.
This way you get a stable situation with full control on it.

Unable to link UIViewController IBOutlets with StoryBoard

I have two UIViewControllers (A and B) in storyboard. The A view controller has a property
#property (nonatomic, retain) IBOutlet UIViewController *viewController;
that I want to link via storyboard to B.
The outlet shows under the the IBOutlets section in storyboard menu but I'm unable to link.
It might seem strange why I'm trying to do that but I need it. Someone knows how to do that?
IBOutlets are connections within a single view controller. Create references to objects inside the view controller so you can use those objects in code.
You cannot create IBOutlets from one view controller to another one. A property is the correct way to go, but you have to assign the property in code. Normally when one view controller creates another one, it might set a reference to itself.
OtherViewController *otherViewController = [OtherViewController alloc] init];
otherViewController.masterViewController = self;
// at this point "otherViewController" has a reference to the current view controller
Now I understand what I need to do. I need to create a custom segue to achieve the same result as when you link a UINavigationController to other ViewController and mark as RootViewController. It is done by segue and not by IBOutlet.
I am a bit late to the party however I put together a segue class to help with this job. View the git repository to see the class in action: https://github.com/datinc/DATOutletSegue.
Basically it uses the identifier of the segue to connect to the parent controller

IBOutlets to other view controllers in storyboard

I want to switch between multiple view controllers with a UIPageViewController. These view controllers are static though so i want to design them in my storyboard. Since one can't use relationships or segues to connect them to the UIPageViewController but a datasource, I need to have a datasource object with an IBOutletCollection holding the pages:
#property (retain, nonatomic) IBOutletCollection(UIViewController) NSArray* pages;
Although, I am not able to connect this outlet to the view controllers in question. I guess thats because view controllers in a story board are treated completely independently like they were in different nib files. Is there a solution though? I don't want to design these view controllers in code.
An IBOutlet is probably not the way to go about this. The best way to do so in my opinion would be to get the nib file using an identifier that you specify in storyboard and then in the viewDidLoad method, type this in and replace the variable name and identifier with the applicable names.
UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:#"myIdentifier"];
Hope this helped you get it working.

Resources