iOS - Load xib and assign objects - ios

I was wondering if anyone knew why I was getting an error when I do this:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"LoadingScreen" owner:self options:NULL];
self = [nib objectAtIndex:0];
self.spinner = [self.subviews objectAtIndex:1];
self.loadingLabel = [self.subviews objectAtIndex:2];
self.shortDescLabel = [self.subviews objectAtIndex:3];
}
return self;
}
-(void)awakeFromNib
{
self.loadingLabel.font = [UIFont fontWithName:#"OpenSans-Regular" size:20];
self.shortDescLabel.font = [UIFont fontWithName:#"FaunaOne-Regular" size:18];
}
I'm getting this error:
2014-07-15 09:32:49.431 [4625:90b] -[UIView setSpinner:]: unrecognized selector sent to instance 0x10d02b350

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"LoadingScreen" owner:self options:NULL];
self = [nib objectAtIndex:0];
By doing this you are initialising self from what ever top most object you are getting from the Xib file.
[UIView setSpinner:]: unrecognized selector sent to instance 0x10d02b350
From the error it is clear you are getting UIView instead of YourCustomView while loading the xib. So probably you may not set the Class of the view to YourCustomView in the Xib file. Check the interface for the class name of your custom view.

It looks like self is being interpreted as a UIView instead of your custom view on this line:
self.spinner = [self.subviews objectAtIndex:1];
This line is asking UIView for a "spinner" property, which it does not have. Thus, causing your error. You need to set your custom class in your NIB so that it is interpreted as your custom view and not a UIView.

Related

Loading a custom UIView from xib

I have a custom UIView which I am loading in this manner
- (id)initWithFrame:(CGRect)frame withDelegate:(id)del
{
self = [super initWithFrame:frame];
UIView *myView;
if (self)
{
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class])
owner:self
options:nil];
for (id object in nibViews)
{
if ([object isKindOfClass:[self class]])
myView = object;
}
myView.frame = frame;
myView.backgroundColor = [UIColor clearColor];
[self addSubview: myView];
}
self.delegate = del;
return self;
}
On loading the view like this when UIView method returns self all the outlets linked in the Interface Builder are nil. Is it not the right way ?
Use this method for load particular xib from bundle
UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:nil];
Try this :
self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class])
owner:self
options:nil] objectAtIndex:0];
Use this
myView =[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil].firstObject];
Or simple you can use
myView = [nibViews firstObject]
As I understand you provide IBOutlet in the xid and when you try to load the view like you provide these values is nil. This is anticipated becouse you create onew viwe and add the view from xib as subview. So the parrent view does not set this values.
to fixe this you need to rework method as loaded your view.
Please try use this:
+ (id)createWithFrame:(CGRect)frame withDelegate:(id)del
{
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class])
owner:nil
options:nil];
<Provide class name> *myView = nibViews[0];
myView.frame = frame;
myView.backgroundColor = [UIColor clearColor];
myView.delegate = del;
return myView;
}

Assign a view controller to a custom .xib

I have a custom re-usable XIB that I've created and assigned it a class subclasses from UIView.
BannerView.xib (file owner set appropriately
BannerView.h : UIView
BannerView.m
Here is the initWithFrame:
-(instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self) {
self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];
}
return self;
}
Everything works fine and I am able to init this custom .xib and add this to my VC:
BannerView *bannerView = [[BannerView alloc]init];
[_profileContentArea addSubview:bannerView];
Although, I would like this custom .xib to have it's own VC and then be able to add as a subview via the VC instead of the above. How would I go about this considering my existing setup at the moment.
your init method is initWithFrame,so you must created BannerView like
BannerView *bannerView = [[BannerView alloc]initWithFrame:frame];
then you can add to ViewController
-(instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self) {
self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];
}
return self;
}
Please notice the initialize steps
+alloc: alloc memory
-init : initialize necessary properties
You've already get the view object when you call alloc and set some properties in init or initWithFrame:
and when you call
self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];
The old view object is gone because you've just set a new one which is from xib
why don't you use -[UIViewController initWithNibName:nibBundle:] you can set nib whatever you want

iOS - Loading a xib

Anyone have any idea why when I use this block of code, it doesn't scale the view to the size of the screen. It looks like it loads the xib file as is and doesn't fit it to the width of the device.
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ReceiptView" owner:self options:NULL];
self = (ReciptView *)[nib objectAtIndex:0];
}
return self;
}
And this is the implementation in the controller:
-(void) bookNowAction
{
ReciptView *v = [[ReciptView alloc] initWithFrame:self.view.frame];
[self.view addSubview:v];
}
You are reassigning self in the if block, after you called super initWithFrame. You are essentially wiping out the effect of that call.

custom UIView and loadNibNamed not working

I am trying to create a custom UIView and have it load in a xib file. The custom UIView is called JtView and here is the code:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
NSLog(#"initWithFrame was called"); // this was called
if (self) {
// Initialization code
[[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:NULL];
[self addSubview:self.view];
}
return self;
}
-(void)awakeFromNib
{
[super awakeFromNib];
[self addSubview:self.view];
}
In creating the xib file (File -> New -> File -> User Interface -> View), I deleted out the main Window and dragged a View from Xcode's object pallette. I tried alt-dragging to the header for JtView but this wasn't working. Do I need to create an association here or should I just leave what XCode created in place? (edit - see comments below for further clarification)
I have also added a UILabel to the xib.
However, when I run in simulator and set the background color to red, the label is not showing up. Do I need to create the UILabel as a reference in the custom UIView? Should I be deleting this or leaving it in place?
thx
edit 1
Here's a screenshot of the connections and the header file:
I solve it adding a class method to the UIView:
+ (id)customView;
+ (id)customView
{
CustomView *customView = [[[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:nil options:nil] lastObject];
// make sure customView is not nil or the wrong class!
if ([customView isKindOfClass:[CustomView class]])
return customView;
else
return nil;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CustomView *customView = [CustomView customView];
//And where you gonna use it add this line:
//this self.view refers to any view (scrollView, cellView...)
[self.view addSubview:customView];
}
I hope it´s gonna help
Try this:
-(void)awakeFromNib {
NSArray *obj = [[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:nil];
[self addSubview:obj[0]];
}
Or if you have an #property IBOutlet named "nibview" you could do:
-(void)awakeFromNib {
[[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:nil];
[self addSubview:self.nibview];
}

How to load CustomView with CustomView.xib when specify class in another XIB?

I create CustomView:UIView with CustomView.xib file.
Now I want to use it by drag view into another XIB (ex: UIViewController.xib) and choose class: customView.
I can load successful when I init CustomView and addSubView to anotherView:
- (void)viewDidLoad{
//Success load NIB
CustomView *aView = [[CustomView alloc] initWithFrame:CGRectMake(40, 250, 100, 100)];
[self.view addSubview:aView];
}
//CustomView.m
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSLog(#"INIT");
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
[[nib objectAtIndex:0] setFrame:frame];
self = [nib objectAtIndex:0];
}
return self;
}
In the case reuse CustomCell by drawing it into another XIB and then specify class as CustomView. I know awakeFromNib is called but don't know how to load CustomView.xib.
how to do that?
*EDIT:
initWithCoder is also called when specify class but it create a loop and crash with loadNibNamed. Why that?
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]) {
NSLog(#"Coder");
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"QSKey" owner:nil options:nil];
[[nib objectAtIndex:0] setFrame:self.bounds];
self = [nib objectAtIndex:0];
}
return self;
}
Directly drag custom xib in your view controller is not possible.But you can do one thing,drag its super class view and set its class to your custom class.And connect its properties to the objects you will place according to your Custom Class.
You can directly load your custom xib using following code:
//load xib using code ....
QSKey *keyView=[[QSKey alloc] init];
NSArray *topObjects=[[NSBundle mainBundle] loadNibNamed:#"QSKey" owner:self options:nil];
for (id view in topObjects) {
if ([view isKindOfClass:[QSKey class]]) {
keyView=(QSKey*)view;
}
}
keyView.label.text=#"CView";
[keyView setFrame:CGRectMake(0, 0, 100, 100)];
[keyView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:keyView];
here label is UILabel object you have used in your custom class as its property.
//Load custom View using drag down objects of type Custom Class Super class.
for (QSKey *aView in self.view.subviews) {
if ([aView isKindOfClass:[QSKey class]]) {
[self addGestureRecognizersToPiece:aView];
aView.label.text=#"whatever!";
}
}
Here label is object of UILabel you have to place on your dragged View to view controller's xib view.Change that view's class to your Custom Class.Then it will will show its label property in outlet connect it to your UILabel object placed over dragged view.
Here is a working code TestTouchonView
And the Screenshot will display as follows.

Resources