1

I'm Creating a custom UIView called InfoAboutBlockView, I'm adding it to my ViewController and it added correctly but when I'm pressing a button inside that custom UIView it won't fire.

I'm creating a xib file in which I design the UIView and then I create the .h and .m files

InfoAboutBlockView.h:

#import <UIKit/UIKit.h>

@interface InfoAboutBlockView : UIView

- (instancetype)init2;

@property (strong, nonatomic) IBOutlet UIView *contentView;

@end

the contentView is the UIView linked to the .h file.

InfoAboutBlockView.m

#import "InfoAboutBlockView.h"

@implementation InfoAboutBlockView


- (instancetype)init2 {
    self = [super init];
    if (self) {
        [self loadViewsFromBundle];
    }
    return self;
}
- (void)loadViewsFromBundle {
    NSString *class_name = NSStringFromClass([self class]);
    [[NSBundle mainBundle] loadNibNamed:class_name owner:self options:nil];
    [self addSubview:self.contentView];
}
- (IBAction)startBlockButtonPressed:(id)sender {
    //This Won't Fire
}

@end

The startBlockButtonPressed is the button connected to the .m file. I set a breakpoint at startBlockButtonPressed but it never fires.

This is how I add the custom subview to my ViewController:

InfoAboutBlockView *infoAboutBlockView = [[InfoAboutBlockView alloc]init2];
[self.view addSubview:infoAboutBlockView];

I tried bringing it to the front using [self.view bringSubviewToFront:infoAboutBlockView]; and checked that it isn't nil and that the button isn't nil but it just won't fire.

Eli Braginskiy
  • 2,867
  • 5
  • 31
  • 46

1 Answers1

4

This is basically the same answer I gave here: https://stackoverflow.com/a/22188740/341994

The problem is that your InfoAboutBlockView has no size. (You never gave it a frame, so its frame is zero.) Therefore it is not touchable. Therefore none of its subviews are touchable. The button is visible, and the InfoAboutBlockView's contentView may be visible, but they are outside the bounds of the InfoAboutBlockView, which is the size of a single point. And a subview outside its superview's bounds cannot be touched.

This would be more evident if you gave the InfoAboutBlockView a weird background color. You won't see that color when it loads.

InfoAboutBlockView *infoAboutBlockView = [[InfoAboutBlockView alloc]init2];
[self.view addSubview:infoAboutBlockView];
infoAboutBlockView.backgroundColor = [UIColor redColor]; // you won't see the red

Another way to see this would be set the InfoAboutBlockView's clipsToBounds to YES; in that case, you wouldn't see the button.

InfoAboutBlockView *infoAboutBlockView = [[InfoAboutBlockView alloc]init2];
[self.view addSubview:infoAboutBlockView];
infoAboutBlockView.clipsToBounds = YES; // you won't see the button!

Basically that is the whole cause of the trouble; you are being fooled by the fact that when clipsToBounds is NO, subviews outside the bounds of a view are visible (that is what clipsToBounds is about). Visible, but (because of the way touch works on iOS) not touchable.

Community
  • 1
  • 1
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • How can it has no size (the frame is zero) if it shows correctly in my `ViewController`? From my understanding if the frame is zero it just wouldn't appear. – Eli Braginskiy Mar 12 '14 at 01:30
  • Its subviews are visible but the view itself has no size. You are creating a UIView by saying `init`, which makes a zero-size view. You have to say `initWithFrame` and give it a size. – matt Mar 12 '14 at 01:31
  • Is there a way to `initWithFrame` with the size i Provided in IB? Or do I always have to provide the size in code? – Eli Braginskiy Mar 12 '14 at 01:32
  • You didn't provide a size in IB. It doesn't come from IB. The `contentView` comes from a nib (IB). But the InfoAboutBlockView comes from saying `alloc` and `init`. – matt Mar 12 '14 at 01:33
  • So basically I always have to provide the size of my custom view's in code? Or is there a different way? – Eli Braginskiy Mar 12 '14 at 01:35
  • 1
    `initWithFrame:` is the _designated initializer_ of UIView. If you create a custom UIView in code you _must_ call it. Either that or assign a `frame`. But if you do nothing at all (as here), you will have a view positioned at zero,zero and with dimensions zero,zero. – matt Mar 12 '14 at 01:39