So I have a custom view created(with a xib file) and I'm trying to use it in another xib file...but it's not showing. In that xib file I have a view and I've set the custom class field to my custom view's name.
However, this view is not showing.
I don't want to draw this view programmatically, I want to use a xib file - how do I do this?
I'm not sure what code I can post up - just tell me in the comments.
I'm not aware of a method to directly drawing a custom view with a xib to another xib, but a thing you can do is:
assing the file owner to the view controller of the xib you want to put the custom one in.
assign the view as an IBOutlet of that controller.
when you need the outlet simply call: [[NSBundle mainBundle] loadNibNamed:#"your_custom_view_xib_name" owner:self options:nil];, at this point the outlet previously created will be set.
set the outlet as subview of the view
Related
I have a .xib file for a view controller and a corresponding Swift file. On click of a button another xib is loaded to show a popup view.
I load the popup view's xib file like this:
let myPopupView : UIView = (Bundle.main.loadNibNamed("myPopupView",
owner: nil,
options:nil)?.first as? UIView)!
Now the popup view has a set of labels for which I want to set selectors. How to do this?
You can't set selectors on views. What you can do is either use buttons or add UIGestureRecognizers (probably tap gesture recognizers) on your views.
You can either make your view a custom subclass of UIView that has IBOutlets to its subviews, or make the file's owner of your XIB file be the view controller that it's being loaded into, and then wire up outlets from the subviews directly into the view controller. The second approach won't work for a situation like a table view cell where you're adding multiple instances of this view to your view controller. In that case you'd need use the first approach of making your top-level view a custom subclass of UIView
I'm sorry but i'm still a bit dumb in UIViews and creating a custom one.
I have a custom view and a xib file that are connected through the XIB IB.
I want to add this view to the storyboard.
What you see in this picture is an empty view which i've connected to the custom view class
When launching the app - i see the exact same view without my custom view being loaded.. what am i missing ?
It is not enough to just link your xib view to the storyboard through the view class name. You should copy the view from your xib (open your xib, select the root view and copy) to your storyboard view controller (select the parent view and paste). You can even open (double tap the xib file in the navigator) your xib in a new window and do a drag drop to the story board. Note that all the property wirings and constrains that you had defined in the xib will be retained when you copy paste your view from xib file.
The answer is actually pretty simple.
I had a recursive init process - meaning that although i did over initWithCoder method, in the xib file, i've set the view class to be my class.
What i should have done is to make my xib file's owner to be my class instead.
And then all the loadFromNibName worked perfectly in my initWithCoder!
I have a XYZViewController (simple UIViewController in storyboard) that is loaded up with the default view. I have a type XYZView for which I have UIView in a .xib file.
In the XYZViewController class, I have defined property for XYZView as an IBOutlet. What is tricky is I don't know how to connect this property to the UIViewController in storyboard (or UIVIew in .xib file) such that —
the IBOutlet is connected to the right UIView
the view in the xib becomes an added subview for the default view of the UIViewController.
(I under the question sounds dodgy and/or I may not have the very right way to explain it, but that's the best I could.)
EDIT: Further clarification may make it easier. I just don't want to myself say:
XYZView *xyzView = [[XYZView alloc] initWithFrame...];
or
[self.view addSubview:xyzView];
Maybe that helps.
OK, from what I tell you have the following...
XYZViewController
The code of this is in XYZViewController.h and .m files.
A .storyboard file
In the storyboard file you have a view controller that you have set the subclass to XYZViewController.
A .xib file
In the xib file you have a single view that you have defined as the subclass XYZView.
Right?
I'm guessing what you have done is the following...
In the .xib file you have laid out the XYZView and put labels, buttons, etc... on it.
The view controller is being created by the storyboard. But now you want to attach the labels and buttons to it.
Right?
If all this is correct then you have a couple of options.
The easiest option
Drop the xib file. Unless that XYZView is being used in multiple places in the app (i.e. inside different view controllers) then you should really be doing all of that layout in the storyboard. Add the buttons and labels to the XYZViewController in the storyboard.
This will then allow you to connect the IBOutlets and IBActions and it will all just work because the storyboard is creating and then setting the outlets and actions.
Next option
Because you have created the view in a xib file you have to load it from that xib file in code and then add it to you view controller.
Something like...
- (void)viewDidLoad
{
[super viewDidLoad];
self.xyzView = [[[NSBundle mainBundle] loadNibNamed:#"XYZView" owner:self options:nil] objectAtIndex:0];
[self.view addSubview:xyzView];
}
Then you can do stuff like ...
self.xyzView.someLabel.text = #"This is the text";
You still won't be able to connect outlets and actions but that's because the view controller is not being created by the xib. It's being created by the storyboard.
This can get all messy though. I'd really only recommend creating a view in a separate xib if it's something that you reuse over and over (like a 5star rating view or something).
What you absolutely can't do
OK, I think I may have thought of what you are doing.
In the storyboard you have set the subclass of the view as XYZView and you are expecting it to pick up the labels and buttons etc... that you have defined in the xib file for XYZView.
This absolutely will not work, ever.
The storyboard and the xib are completely separate objects. If you want to use them together then code is involved in loading a view from a nib and then adding it to a view controller created in a storyboard.
I am trying to create an accessoryInputView to augment the keyboard with some app-specific keys.
I am using a Storyboard based design approach to keep the the UI separated from the application logic.
I cannot seem to understand how to create the new view and associated it with the textView. Is it possible?
You can check this sample project from Apple:
https://developer.apple.com/library/ios/samplecode/KeyboardAccessory/Introduction/Intro.html
To achieve the same result that in the sample, you must drag and drop an UIView instance into the "Document Outline" window when your storyboard is open.
It is the window on the left.
Then you have to create an IBOutlet in your controller to access the view and set it as an inputAccessoryView.
In case anyone else is trying to do this, let me record what I ended up doing.
I created a new XIB with the accessoryView I wanted in it. I could not figure out how to assign
the inputAccessoryView directly into a storyboard design, so I did the following.
I made the fileOwner of the XIB as the controller class that contains the textView that needs the accessoryView and assigned the view to a IBOutlet in that class. That allows me to load the XIB and auto-assign it to the IBOutlet.
Then in the viewDidLoad, I assign the IBOutlet to the textView that needs it. It works well and allows me to do all the UI work in IB and keep the logic in the controller. I guess I can consider setting the inputAccessoryView as 'logic' and not UI design and consider this a good design. Not stellar, since IB does not allow setting the inputAccessoryView directly from a XIB or creating views in a storyboard that are not part of the flow of the app.
The code in viewDidLoad looks like:
- (void) viewDidLoad
{
...
[super viewDidLoad];
[[NSBundle mainBundle] loadNibNamed:#"NoteInputAccessoryView" owner:self options:nil];
_noteTextView.inputAccessoryView=_noteInputAccessoryView;
...
}
Sorry for perhaps noob question, guys. I'm new to iOS development.
How can I create view controller that is defined in XIB ?
When you create new class inherited from UIViewController in Xcode via "New File" and mark with XIB checkbox it creates xib file that doesn't have viewController element. But rather it has placeholder which points to UIViewController which is defined in the code.
But I see that you can create controller itself in Interface Builder and specify customClass for it.
Unfortunately it doesn't work for me. I get loaded the "EmbeddedViewController" nib but the view outlet was not set error in run-time. But I believed view property must be set by resource loader automatically since everything is defined via XIB. It works that way for TableView and its cells for example.
Could you please provide example how to do it ?
I created sample project: https://github.com/cppexpert/SampleWithNib
The controller in question is EmbeddedViewController
Create one Xib per UIViewController
Each Xib have File's Owner object for you to set UIViewController class there. Click File's Owner and choose EmbeddedViewController on it's class
Then drag main UIView not UIViewController class to there, then hook up this view with file's owner as view. UIViewController just use to drag to StoryBoard base project.
https://github.com/lequysang/gitfiles02/blob/master/SampleWithNib-master.zip
Turned out these controls exist in IB for Storyboard projects.
When you create a view controller with xib via "new file", Xcode generates an UIView and connects it with view outlet automatically. Seems like you changed something after Xcode generated the xib file. In that case you need to connect a view to the view outlet manually.
If you create a new view in xib.set the file owner to your custom class.
Or if you simply want to create a view.
Then
NSArray* test1 = [[NSBundle mainBundle] loadNibNamed:#"View" owner:self options:nil];
self.myViewFromNib = [test1 objectAtIndex:0];
Where myViewFromNib is your view object and "View" is your nib name.