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
Related
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.
I have a view controller which as one of its views a container view (in IB storyboard) which embeds a table view controller, which in turn has a container view that embeds yet another view controller. In this last view controller I set up a delegate protocol with a weak synthesized delegate property as an IBOutlet. The very first view controller is what I want to receive the delegate methods from the last and I added the protocol <...> to it.
The problem is that I have not figured out a way while in storyboard (or otherwise) to link the IBOutlet delegate of the last view controller to the first view controller which follows the protocol so the last can send the first messages. I thought I could just drag and drop (with the control key) but all I find is segue options on the destination. It seems even though the delegate appears in the outlet connections window, it will not connect to ANY view controller in my project.
Can't ANY view controller be a delegate of another's protocol? And can be linked in IB? If I cannot do it with IB, I don't know how to make another VC a delegate upstream.
Any advice would be appreciated. Thanks.
You cannot connect IBOutlets between view controllers. You need to do it in code. You'll have to go through the chain of childViewController to get from the first controller to the last -- if I understand your structure properly, from the first view controller:
LastController *last = ((UIViewController *)self.childViewControllers[0]).childViewControllers[0];
last.delegate = self;
I asked a similar question Interface Builder won't allow connections to custom UIView class? I ultimately opened a bug with Apple. After a few follow up queries from Apple, I haven't heard any kind of resolution.
I have a standard extended UIViewController (called ParentViewController, or PVC), and want to have a container or child view which will be driven by ChildViewController or CVC.
I see that programmatically, that in PVC I can call addChild:CVC and manage calls such as didMoveToParentViewController, etc.... However, I am hoping that there is a way to do this with Interface Builder.
So I laid out an instance of PVC, then dragged a ContainerView onto PVC's view which creates a segue to a child window. In that window I assigned the class type of ChildViewController. This looks great so far, but how do I reference this programmatically from PVC? Let's try the usual: In PVC class extension, I have declared:
#property (nonatomic, strong) IBOutlet ChildViewController* cvc;
When I switch to IB, and highlight the PVC instance, and select the connections inspector, I see my cvc property but I cannot hook it up to my containerView instance (even though its class type is set appropriately). It allows me to drag (draw the line), but does not let me actually hook it up. Why??
I am thinking that this just isn't possible with IB, but perhaps I'm looking at this incorrectly?
I have read Apple's docs on child views and am prepared to do this programmatically if I can't get IB to do what I'm intending.
cvc is a child view controller of PVC, so you can get a reference to it with the childViewControllers property, which you would do in code rather than hooking up an outlet in IB. In PVC's viewDidLoad method, do this:
self.cvc = (ChildViewController *)self.childViewControllers[0];
Xcode will not allow you to hook up outlets between two different controllers, so even though cvc is embedded as a child view controller, it's still a different 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.
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.