Custom UIView loaded from Xib

I created a custom subclass of UIView along with an xib file and declared IBOutlets and IBActions in a 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 dragged into a UIView to present my custom view. I have installed:

  • File Owner = in my custom class
  • Set drag and drop in UIView to my custom class.

Then I added a few buttons that are connected to the above methods.

Inside 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 came 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]; } 

Question When I click one of the buttons, the application crashes: Topic 1: EXC_BAD_ACCESS (code = 2, address = 0xb0c

Can anyone help me with this. I feel like I'm probably mistaken in creating and loading custom uiviews from xibs.

If you need more information, let me know. Many thanks.

Future link When creating a custom view using xib, DO NOT set the owner of the files. Instead, create all your IBOutlets and IBActions as usual, and then pin them, open the Utilities tab and drag the control there.

enter image description here

+5
source share
3 answers

• File owner = in my custom class

Wrong. The file owner must be empty. The view itself is the owner of the files. This means that you must connect all actions and outputs to ContactUsView in xib.

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

...

self = (ContactUsView *) object;

After passing self as the owner parameter. You change it. This means that previously allocated ContactUsView ( self ) will be destroyed, since -loadNibNamed:owner:options: will not save it. If you apply my first tip, you should send nil as the owner parameter

for It is not necessary to use only array[0] , because it is always your opinion if you have a valid hierarchy of representations in xib

+4
source

If you are loading a UIView for xib, then you must 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 change your customview class in the identity inspector, and also make sure your IBActions are connected to the methods of this class. enter image description here

enter image description here

+2
source

You can use a delegate for this so you can do it

  @protocol CustomViewDelegate <NSObject> - (void)callButtonPressed:(id)sender; - (void)emailButtonPressed:(id)sender; - (void)displayCloseButtonPressed:(id)sender; @end @interface ContactUsView : UIView @property (nonatomic, weak) IBOutlet UIButton *displayCloseButton; @property (nonatomic, weak) id<CustomViewDelegate> ButtonDelegate; - (IBAction)callButtonPressed:(id)sender; - (IBAction)emailButtonPressed:(id)sender; - (IBAction)displayCloseButtonPressed:(id)sender; @end 

and in the .m file

 - (IBAction)callButtonPressed:(id)sender { [self.ButtonDelegate callButtonPressed:sender]; } - (IBAction)emailButtonPressed:(id)sender{ [self.ButtonDelegate emailButtonPressed:sender]; } - (IBAction)displayCloseButtonPressed:(id)sender{ [self.ButtonDelegate displayCloseButtonPressed:sender]; } 

After that just set the delegate with refrence viewcontroller and use that delegate here

 - (void)viewWillAppear:(BOOL)animated 

{

 ContactUsView *contactUs = [[ContactUsView alloc] initWithFrame:CGRectZero]; contactUs.ButtonDelegate = self; 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]; 

}

 - (void)callButtonPressed:(id)sender 

{}

 - (void)emailButtonPressed:(id)sender 

{}

 - (void)displayCloseButtonPressed:(id)sender 

{}

I did it and work great

0
source

Source: https://habr.com/ru/post/1208419/


All Articles