How to load XIB using top level ViewController?

I have a tip with the root element of a view controller, for example:

enter image description here

so that I can position elements relative to the top and bottom guides of the layout using automatic layout.

When I first tried to load this tip using

SearchViewControllerPro* searchViewController = [[SearchViewControllerPro alloc]initWithNibName:@"SearchViewControllerPro" bundle:[NSBundle mainBundle]]; 

I got the following exception at runtime:

The application terminated due to the uncaught exception 'NSInternalInconsistencyException', reason: '- [UIViewController _loadViewFromNibNamed: bundle:] loaded the thread “SearchViewControllerPro”, but the exit viewpoint was not set. ''

Influencing the error, I was told that the owner of the xib file should be set to the class of my view controller, and the output for the view should be set to a view object in xib. If I do this, I get the following runtime error:

The application terminated due to the uncaught exception "UIViewControllerHierarchyInconsistency", reason: "View can only be associated with at most one view controller at a time! View>. Remove this link before linking this view to.

This is not a surprise since the view is associated with both the owner of the file and the top-level view controller. But how can I say at runtime that both of them are actually the same thing instead of two separate objects?

Edit: When I try to disconnect ViewController from nib, so,

 NSArray* xibContents = [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:nil options:nil]; SearchViewControllerPro* mapSearchViewController = [xibContents lastObject]; 

this is also not useful:

The application terminated due to the uncaught exception "NSUnknownKeyException", Reason: '[setValue: forUndefinedKey:]: this class does not match the key value for representing the key.

Temporary solution:

I found a solution, but it is not very. Despite the structure, as shown in IB, the view controller is not the last object in xib. Therefore, I have:

 __block SearchViewControllerPro* mapSearchViewController = nil; [xibContents enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[SearchViewControllerPro class]]) { mapSearchViewController = obj; } }]; 

and it seems to work without crashing at runtime. However, this is all but pure code.

+7
ios uiviewcontroller interface-builder uiview xib
source share
3 answers

how can I tell the runtime that both of them are actually the same instead of two separate objects?

You cannot, because it is not the same thing. You have created two SearchViewControllerPro intentions.

You need to either highlight-initialize the SearchViewControllerPro instance, or unlock it from nib.

If you decide to create a ViewController in nib, the usual way to access it is the same as accessing any other element (view, button, text field) created in the bank.

Add output to the FilesOwner object, connect the connection in the interface builder, and be sure to pass the object when you unlock nib.

For example, if you want the object that unpacks nib to be FileOwner:

 [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:self options:nil]; 
+4
source share

The following works the same way and (at least for me) a little more explicit that creating an output for the ViewController:

 NSArray* xibContents = [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:nil options:nil]; SearchViewControllerPro* mapSearchViewController = [xibContents objectAtIndex:0]; 
+3
source share
 if (isIPad) { [[NSBundle mainBundle] loadNibNamed:@"ABC_iPad" owner:self options:nil]; } else{ [[NSBundle mainBundle] loadNibNamed:@"ABC_iPhone" owner:self options:nil]; } 
0
source share

All Articles