Thank you all. I did find a way to do what I wanted Create your UIView with the IBOutlets you need Create the xib in IB, design it to you liking and link it like this: The File's Owner is of class UIViewController (No custom subclass, but the "real" one). The File Owner's view is connected to the main view and its class is declared as the one from step 1) Connect your controls with the IBOutltes The DynamicViewController can run its logic to decide what view/xib to load.
Once its made the decission, in the loadView method put something like this: NSArray* nibViews = NSBundle mainBundle loadNibNamed:@"QPickOneView" owner:self options:nil; QPickOneView* myView = nibViews objectAtIndex: 1; myView. Question = question That's it! The main bundle's loadNibNamed method will take care of initializing the view and create the connections Now the ViewController can display a view or another depending on the data in memory, and the "parent" screen doesn't need to be bother with this logic Gonso.
Thank you all. I did find a way to do what I wanted. Create your UIView with the IBOutlets you need.
Create the xib in IB, design it to you liking and link it like this: The File's Owner is of class UIViewController (No custom subclass, but the "real" one). The File Owner's view is connected to the main view and its class is declared as the one from step 1). Connect your controls with the IBOutltes.
The DynamicViewController can run its logic to decide what view/xib to load. Once its made the decission, in the loadView method put something like this: NSArray* nibViews = NSBundle mainBundle loadNibNamed:@"QPickOneView" owner:self options:nil; QPickOneView* myView = nibViews objectAtIndex: 1; myView. Question = question; That's it!
The main bundle's loadNibNamed method will take care of initializing the view and create the connections. Now the ViewController can display a view or another depending on the data in memory, and the "parent" screen doesn't need to be bother with this logic. Gonso.
1 I have a very similar problem - I simply want to load a UIView from an xib file. These steps don't work for me - the app crashes with "bad access" soon after adding the loaded view as a subview. – Justicle May 27 '09 at 0:18 For iPhone 3.0, use objectAtIndex:0 to get the first element.
This crashes for me exactly as described by Justicle. Any idea why? – brainfsck Aug 11 '09 at 21:19 1 +1 it worked perfectly for me.
I wanted to add multiple views that had the one view controller (im using a flip view scenario where a section of the view spins) I had to make the index on the array 0 (iPhone 3.0) – Aran Mulholland Apr 27 '10 at 10:08 14 This is the correct answer, however, the code should be modified so that it loops through nibViews and does a class check on each object, so that way you are certainly getting the correct object. ObjectAtIndex:1 is a dangerous assumption. – Jasconius Jul 30 '10 at 20:23 1 Jasconius is right.
You should loop through the nibViews array like this: gist.github. Com/769539 – leviathan Jan 7 at 14:50.
There is also an easier way to access the view instead of dealing with the nib as an array. 1) Create a custom View subclass with any outlets that you want to have access to later. --MyView 2) in the UIViewController that you want to load and handle the nib, create an IBOutlet property that will hold the loaded nib's view, for instance in MyViewController (a UIViewController subclass) @property (nonatomic, retain) IBOutlet UIView *myViewFromNib; (dont forget to synthesize it and release it in your .
M file) 3) open your nib (we'll call it 'myViewNib. Xib') in IB, set you file's Owner to MyViewController 4) now connect your file's Owner outlet myViewFromNib to the main view in the nib. 5) Now in MyViewController, write the following line: NSBundle mainBundle loadNibNamed:@"myViewNib" owner:self options:nil; Now as soon as you do that, calling your property "self.
MyViewFromNib" will give you access to the view from your nib!
It was really helpful – fyasar Nov 1 '10 at 8:59 1 Will it work for for main controller view (self. View)? For some reasons I need to load main view from nib after standard controller init method.
Reason - complex sublassing structure – Lukasz Dec 10 '10 at 15:12.
I'm not sure what some of the answers are talking about, but I need to put this answer here for when I search in Google next time. Keywords: "How to load a UIView from a nib" or "How to load a UIView from an NSBundle. " Here's the code almost 100% straight up from the Apress Beginning iPhone 3 book (page 247, "Using The New Table View Cell"): - (void)viewDidLoad { super viewDidLoad; NSArray *bundle = NSBundle mainBundle loadNibNamed:@"Blah" owner:self options:nil; Blah *blah; for (id object in bundle) { if (object isKindOfClass:Blah class) blah = (Blah *)object; } self.
View addSubview: blah; } This supposes you have a UIView subclass called Blah, a nib called Blah which contains a UIView which has its class set to Blah.
If you use the isKindOf you are protected from Bundle structure changes. – Yar Jul 7 '10 at 1:57.
You should not be setting the class of your view controller to be a subclass of UIView in Interface Builder. That is most definitely at least part of your problem. Leave that as either UIViewController, some subclass of it, or some other custom class you have.As for loading only a view from a xib, I was under the assumption that you had to have some sort of view controller (even if it doesn't extend UIViewController, which may be too heavyweight for your needs) set as the File's Owner in Interface Builder if you want to use it to define your interface.
I did a little research to confirm this as well. This is because otherwise there would be no way to access any of the interface elements in the UIView, nor would there be a way to have your own methods in code be triggered by events. If you use a UIViewController as your File's Owner for your views, you can just use initWithNibName:bundle: to load it and get the view controller object back.
In IB, make sure you set the view outlet to the view with your interface in the xib. If you use some other type of object as your File's Owner, you'll need to use NSBundle's loadNibNamed:owner:options: method to load the nib, passing an instance of File's Owner to the method. All its properties will be set properly according to the outlets you define in IB.
One point, I believe that this view controller should be based in some manner on UIViewController to take advantage of all its functionality. Also, you don't have to make the File's Owner to a view controller. One can simply load the nib and grab the view out of that nib -- I don't have the code here but I know you can do it.
– Lyndsey Ferguson May 14 '09 at 14:02 That's what I was trying to research. Everything I found indicated that there needs to be some sort of File's Owner linked to the view in order to access it. You could of course write something more hackish that iterated over the top-level objects in the nib and extract the view that way, but I was trying to stay away from suggesting that.
– Marc W May 14 '09 at 14:18 I'm reading the Apress book, "Beginning iPhone Development: Exploring the iPhone SDK" and they discussed this method at chapter 9: Navigation Controllers and Table Views. It didn't seem too complicated. – Lyndsey Ferguson May 14 '09 at 14:29 I'd be curious to see how they say it's done.
I don't have a copy of that book at the moment. – Marc W May 14 '09 at 14:43 You could always ping Jeff LaMarche or Dave Mark via Twitter. Can't remember the latter's handle offhand, but Jeff is @jeff_lamarche.
– Jim Dovey May 14 '09 at 17:18.
I too wanted to do something similar, this is what I found: (SDK 3.1.3) I have a view controller A (itself owned by a Nav controller) which loads VC B on a button press: In AViewController. M BViewController *bController = BViewController alloc initWithNibName:@"Bnib" bundle:nil; self. NavigationController pushViewController:bController animated:YES; bController release; Now VC B has its interface from Bnib, but when a button is pressed, I want to go to an 'edit mode' which has a separate UI from a different nib, but I don't want a new VC for the edit mode, I want the new nib to be associated with my existing B VC.So, in BViewController.
M (in button press method) NSArray *nibObjects = NSBundle mainBundle loadNibNamed:@"EditMode" owner:self options:nil; UIView *theEditView = nibObjects objectAtIndex:0; self. EditView = theEditView; self. View addSubview:theEditView; Then on another button press (to exit edit mode): editView removeFromSuperview; and I'm back to my original Bnib.
This works fine, but note my EditMode. Nib has only 1 top level obj in it, a UIView obj.It doesn't matter whether the File's Owner in this nib is set as BViewController or the default NSObject, BUT make sure the View Outlet in the File's Owner is NOT set to anything. If it is, then I get a exc_bad_access crash and xcode proceeds to load 6677 stack frames showing an internal UIView method repeatedly called... so looks like an infinite loop.
(The View Outlet IS set in my original Bnib however) Hope this helps.
Reading between the lines, this helped me out too. – petert Apr 22 '10 at 16:05 According to the information at link you shouldn't manipulate view controllers in this way. – T.
Markle Apr 18 at 19:03.
The previous answer does not take into account a change in the NIB (XIB) structure that occurred between 2.0 and 2.1 of the iPhone SDK. User contents now start at index 0 instead of 1. You can use the 2.
1 macro which is valid for all version 2.1 and above (that's two underscores before IPHONE: // Cited from previous example NSArray* nibViews = NSBundle mainBundle loadNibNamed:@"QPickOneView" owner:self options:nil; int startIndex; #ifdef __IPHONE_2_1 startIndex = 0; #else startIndex = 1; #endif QPickOneView* myView = nibViews objectAtIndex: startIndex; myView. Question = question; We use a technique similar to this for most of our applications. Barney.
I found this blog posting by Aaron instructor, Cocoa ninja) to be very enlightening. Even if you don't adopt his modified approach to loading NIB files through a designated initializer you will probably at least get a better understanding of the process that's going on. I've been using this method lately to great success!
This is a great question (+1) and the answers were almost helpful ;) Sorry guys, but I had a heck of a time slogging through this, though both Gonso & AVeryDev gave good hints. Hopefully, this answer will help others. MyVC is the view controller holding all this stuff.
MySubview is the view that we want to load from a xib In MyVC. Xib, create a view of type MySubView that is the right size & shape & positioned where you want it. In MyVC.
H, have IBOutlet MySubview *mySubView // ... @property (nonatomic, retain) MySubview *mySubview; In MyVC. M, @synthesize mySubView; and don't forget to release it in dealloc. In MySubview.
H, have an outlet/property for UIView *view (may be unnecessary, but worked for me. ) Synthesize & release it in . M In MySubview.
Xib set file owner type to MySubview, and link the view property to your view. Lay out all the bits & connect to the IBOutlet's as desired Back in MyVC. M, have NSArray *xibviews = NSBundle mainBundle loadNibNamed: @"MySubview" owner: mySubview options: NULL; MySubview *msView = xibviews objectAtIndex: 0; msView.
Frame = mySubview. Frame; UIView *oldView = mySubview; self. View insertSubview: msView aboveSubview: mySubview; self.
MySubview = msView; oldCBView removeFromSuperview; The tricky bit for me was: the hints in the other answers loaded my view from the xib, but did NOT replace the view in MyVC (duh! ) -- I had to swap that out on my own. Also, to get access to mySubview's methods, the view property in the .
Xib file must be set to MySubview. Otherwise, it comes back as a plain-old UIView. If there's a way to load mySubview directly from its own xib, that'd rock, but this got me where I needed to be.
None of the answers explain how to create the stand alone XIB that is the root of this question. There is no XCode 4 option to "Create New XIB File". To do this 1) Choose "New File..." 2) Choose the "User Interface" category under the iOS section 3) Choose the "View" item 4) You will then be prompted to choose an iPhone or iPad format This may seem simple but it can save you a few minutes poking around for it since the word "XIB" does not appear anywhere.
AVeryDev 6) To attach the loaded view to your view controller's view: self. View addSubview:myViewFromNib; Presumably, it is necessary to remove it from the view to avoid memory leaks. To clarify: the view controller has several IBOutlets, some of which are connected to items in the original nib file (as usual), and some are connected to items in the loaded nib.
Both nib's have the same owner class. The loaded view overlays the original one. Nt: set the opacity of the main view in the loaded nib to zero, then it won't obscure the items from the original nib.
This is something that ought to be easier. I ended up extending UIViewController and adding a loadNib:inPlaceholder: selector. Now I can say self.
MySubview = (MyView *)self loadNib:@"MyView" inPlaceholder:mySubview; Here's the code for the category (it does the same rigamarole as discussed above): @interface UIViewController (nibSubviews) - (UIView *)viewFromNib:(NSString *)nibName; - (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder; @end @implementation UIViewController (nibSubviews) - (UIView *)viewFromNib:(NSString *)nibName { NSArray *xib = NSBundle mainBundle loadNibNamed:nibName owner:self options:nil; for (id view in xib) { // have to iterate; index varies if (view isKindOfClass:UIView class) return view; } return nil; } - (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder { UIView *nibView = self viewFromNib:nibName; nibView setFrame:placeholder. Frame; self. View insertSubview:nibView aboveSubview:placeholder; placeholder removeFromSuperview; return nibView; } @end.
You can also use UIViewController's initWithNibName instead of loadNibNamed. It is simpler, I find. UIViewController *aViewController = UIViewController alloc initWithNibName:@"MySubView" bundle:nil; self.
Subview addSubview:aViewController. View; aViewController release; // release the VC Now you just have to create MySubView. Xib and MySubView.
H/m. In MySubView. Xib set the File's Owner class to UIViewController and view class to MySubView.
You can position and size of the subview using the parent xib file.
I had reason to do the same thing (programmatically loading a view from a XIB file), but I needed to do this entirely from the context of a subclass of a subclass of a UIView (i.e. Without involving the view controller in any way). To do this I created this utility method: + (id) initWithNibName:(NSString *)nibName withSelf:(id)myself { NSArray *bundle = NSBundle mainBundle loadNibNamed:nibName owner:myself options:nil; for (id object in bundle) { if (object isKindOfClass:myself class) { return object; } } return nil; } Then I call it from my subclass' initWithFrame method like so: - (id)initWithFrame:(CGRect)frame { self = Utilities initWithNibName:@"XIB1" withSelf:self; if (self) { // Initialization code.
} return self; } Posted for general interest; if anyone sees any problems without doing it this way, please let me know.
This technique does not work for me. I want to reuse my views in IB so I need to be able to init the view from inside its self. The only way to do this is to do the following - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (nibNameOrNil) { if (!nibBundleOrNil) { nibBundleOrNil = NSBundle mainBundle; } NSArray* bundle = nibBundleOrNil loadNibNamed:nibNameOrNil owner:self options:nil; for (NSObject* object in bundle) { if (object isKindOfClass:UIView class) { __contentView = (UIView*)object retain; __contentView.
Frame = self. Bounds; self addSubview:__contentView; } } self. BackgroundColor = UIColor clearColor; } return self; } I need a better solution then releasing the view object every time I init it.
You should not be setting the class of your view controller to be a subclass of You should not be setting the class of your view controller to be a subclass of UIViewUIView in Interface Builder. That is most definitely at least part of your problem. Leave that as either in Interface Builder.
That is most definitely at least part of your problem. Leave that as either UIViewControllerUIViewController, some subclass of it, or some other custom class you have. , some subclass of it, or some other custom class you have.
As for loading only a view from a xib, I was under the assumption that you had to have some sort of view controller (even if it doesn't extend UIViewController, which may be too heavyweight for your needs) set as the File's Owner in Interface Builder if you want to use it to define your interface. I did a little research to confirm this as well. This is because otherwise there would be no way to access any of the interface elements in the UIViewAs for loading only a view from a xib, I was under the assumption that you , nor would there be a way to have your own methods in code be triggered by events.
Had to have some sort of view controller (even if it doesn't extend UIViewController, which may be too heavyweight for your needs) set as the File's Owner in Interface Builder if you want to use it to define your interface. I did a little research to confirm this as well. This is because otherwise there would be no way to access any of the interface elements in the UIView, nor would there be a way to have your own methods in code be triggered by events.
If you use a UIViewController as your File's Owner for your views, you can just use initWithNibName:bundle: to load it and get the view controller object back. In IB, make sure you set the view outlet to the view with your interface in the xib. If you use some other type of object as your File's Owner, you'll need to use NSBundle's loadNibNamed:owner:options: method to load the nib, passing an instance of File's Owner to the method.
All its properties will be set properly according to the outlets you define in IB.
There is also an easier way to access the view instead of dealing with the nib as an array.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.