IBOutlets to other view controllers in storyboard - ios

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.

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.

Create Relationship Segues

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.

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

iOS Storyboard - Custom Outlet from a ViewController to another?

I am trying to implement something similar to AplitView where you can hace separate scenes in storyboard and connect a viewController to another one as an outlet. Is this possible?
#Interface MenuNavigationController : UINavigationController
#property (nonatomic, strong) IBOUtlet MenuViewcontroller *menuViewController;
#end
In interfaceBuilder I want to drag and drop, and assign another viewController to my outlet
Xcode won't allow you to make connections between different scenes in a storyboard. It does allow such connections for the container view controllers that it knows about, like UISplitViewController, but not for your own. See Linking child view controllers to a parent view controller within storyboard for some useful ideas on this topic.

Resources