Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom UIView loaded from Xib

I have created a custom subclass of UIView along with a xib file and declared IBOutlets and IBActions within the custom class.

@interface ContactUsView : UIView

@property (nonatomic, weak) IBOutlet UIButton *displayCloseButton;

- (IBAction)callButtonPressed:(id)sender;
- (IBAction)emailButtonPressed:(id)sender;
- (IBAction)displayCloseButtonPressed:(id)sender;

@end

In the xib file I have dragged in a UIView to represent my custom view. I have set:

  • Files owner = to my custom class
  • Have set the dragged in UIView to my custom class.

I have then added various buttons which are hooked up to the 3 methods stated above.

Inside the ContactUsView.m I have the following:

- (id)initWithFrame:(CGRect)frame 
{
    if (self = [super initWithFrame:frame]) {
        NSArray* array = [[NSBundle mainBundle] loadNibNamed:@"ContactUsView" owner:self options:nil];
        for (id object in array) {
            if ([object isKindOfClass:[ContactUsView class]])
                self = (ContactUsView *)object;
        }
    }
    return self;
}

When I come to create this view I do the following:

- (void)viewWillAppear:(BOOL)animated
{
    ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero];

    CGPoint origin = self.view.frame.origin;
    CGSize size = self.view.frame.size;
    [contactUs setFrame:CGRectMake(origin.x,
                              CGRectGetMaxY(self.view.frame) - 100,
                              size.width,
                              contactUs.frame.size.height)];

    [self.view addSubview:contactUs];
}

Issue When I press on one of the buttons the application crashes with: Thread 1: EXC_BAD_ACCESS(code=2, address=0xb0c

Can anyone help me with this. I feel like I am probably making a mistake somewhere in regards to creating and loading custom uiviews from xibs.

If you require anymore information let me know. Many thanks.

Future reference When creating a custom view using a xib DO NOT set the files owner. Instead create all your IBOutlets and IBActions as you normally would and then to hook them up open the Utilities tab and control drag from there.

enter image description here

like image 843
pls Avatar asked Dec 05 '14 11:12

pls


People also ask

How do I load a custom view in storyboard?

Using a custom view in storyboardsOpen up your story board and drag a View (colored orange below for visibility) from the Object Library into your view controller. Set the view's custom class to your custom view's class. Create an outlet for the custom view in your view controller.

What is difference between XIB and NIB?

NIBs and XIBs are effectively the same thing: XIBs are newer and are used while you're developing, whereas NIBs are what get produced when you create a build. In modern versions of iOS and macOS, NIBs and XIBs have effectively been replaced by storyboards, although you may still meet them if you work on older projects.


2 Answers

• Files owner = to my custom class

Wrong. Files owner should be empty. The view itself is files owner. It means that you should connect all actions and outlets with ContactUsView in your xib.

[[NSBundle mainBundle] loadNibNamed:@"ContactUsView" owner:self options:nil]

...

self = (ContactUsView *)object;

After you passed self as ownerparameter. You changing it. Which means that previously allocated ContactUsView (self) will be destroyed since -loadNibNamed:owner:options: do not retain it. If you apply my first advice you should send nil as owner parameter

forloop here is not necessary use just array[0], because this is always your view if you have valid views hierarchy in your xib

like image 142
Silmaril Avatar answered Sep 19 '22 14:09

Silmaril


If you are loading a UIView for an xib then you should create a class method to load the view.

In your customview.h

+(id)customView;

& in your customview.m

+ (id)customView
{
    CustomView *customView = [[[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:nil options:nil] lastObject];
    if ([customView isKindOfClass:[CustomView class]])
        return customView;
    else
        return nil;
}

You can initialize it anywhere using:

CustomView *myView = [CustomView customView];

EDIT: Make sure you have changed your customview's class in identity inspecter & also make sure your connection of IBActions are with that class' methods.enter image description here

enter image description here

like image 20
Ajay Avatar answered Sep 18 '22 14:09

Ajay