Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton targets not working if a UIView is added as a subview

I have a UIButton. It has two subviews. I then call:

[createButton addTarget:self action:@selector(openComposer) forControlEvents:UIControlEventTouchUpInside];

If I tap the parts of the UIButton that aren't covered but one of its subviews, it works fine. However if I tap one of the subviews instead, it does not trigger the action.

On both subviews, I has .userInteractionEnabled set to YES.

Both subviews are plain UIViewss with a frame and backgroundColor.

How can I get the tap to "pass through" the UIView and onto the UIButton?

Thanks

EDIT: I need to use UIControlEvents because I need UIControlEventTouchDown.

EDIT 2:

Here is the code for the button.

@interface CreateButton ()

@property (nonatomic) Theme *theme;
@property (nonatomic) UIView *verticle;
@property (nonatomic) UIView *horizontal;
@property (nonatomic) BOOL mini;

@end

@implementation CreateButton

#pragma mark - Accessors

- (UIView *)verticle {
    if (! _verticle) {
        _verticle = [[UIView alloc] init];
        _verticle.backgroundColor = [self.theme colorForKey:@"createButtonPlusBackgroundColor"];
        _verticle.userInteractionEnabled = NO;
    }
    return _verticle;
}

- (UIView *)horizontal {
    if (! _horizontal) {
        _horizontal = [[UIView alloc] init];
        _horizontal.backgroundColor = [self.theme colorForKey:@"createButtonPlusBackgroundColor"];
        _verticle.userInteractionEnabled = NO;
    }
    return _horizontal;
}

#pragma mark - Init

- (instancetype)initWithTheme:(Theme *)theme frame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _theme = theme;

        self.layer.cornerRadius = roundf(frame.size.width / 2);
        self.layer.shadowColor = [UIColor blackColor].CGColor;
        self.layer.shadowOpacity = .1f;
        self.layer.shadowOffset = CGSizeZero;
        self.layer.shadowRadius = 15.f;
        self.backgroundColor = [self.theme colorForKey:@"createButtonBackgroundColor"];

        [self addSubview:self.verticle];
        [self addSubview:self.horizontal];

        [self addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchDown];
        [self addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchUpInside];
        [self addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchUpOutside];
    }
    return self;
}

#pragma mark - Actions

- (void)animate {
    [UIView animateWithDuration:0.2 delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:8 options:kNilOptions animations:^{
        if (self.mini) {
            self.transform = CGAffineTransformMakeScale(1.0, 1.0);
            self.mini = NO;
        } else {
            self.transform = CGAffineTransformMakeScale(0.90, 0.90);
            self.mini = YES;
        }
    } completion:nil];
}

#pragma mark - UIView

- (void)layoutSubviews {
    CGSize size = self.bounds.size;

    NSInteger width = 3;
    NSInteger verticleInset = 12;
    self.verticle.frame = CGRectMake((size.width - width) / 2, verticleInset, width, size.height - (verticleInset * 2));
    self.horizontal.frame = CGRectMake(verticleInset, (size.height - width) / 2, size.width - (verticleInset * 2), width);
}

@end
like image 887
Jason Silberman Avatar asked Jul 17 '14 22:07

Jason Silberman


People also ask

How can I check if UIButton is pressed?

If you want to check If UIButton is Pressed or not, You should handle TouchDown Handler and change button's state to pressed in touchDown hadnler. You can track ToucUpInside method to Change state of button to Not-pressed again.

How do I add a subview to a storyboard?

Select the subview and drag over the view entry in the Objects Explorer of storyboard. Once you leave the mouse hold, the parent view will have a triangle indicating your subview has become its child and the subview will have a bigger indent than your view.

What is a Subview?

Noun. subview (plural subviews) (computing, graphical user interface) A secondary or subsidiary view.


2 Answers

Set userInteractionEnabled to NO for your subviews to let touches pass through them and onto your button.

Also make sure to change _verticle.userInteractionEnabled = NO; in your lazy-loader for your horizontal property to _horizontal.userInteractionEnabled = NO; as I believe that's a typo.

like image 200
TylerP Avatar answered Oct 22 '22 08:10

TylerP


please use the code like below (replace the 'ViewControllerFilterCategory' with your own one + the nibName) to add the controller from nib (child one) as the child controller of current controller before adding the view as sub view. Then the iOS will call actions attached to the child controller as you expect:

    let vcCats = ViewControllerFilterCategory(nibName: "ViewControllerFilterCategory", bundle: Bundle.main);
    self.addChildViewController(vcCats);
    self.view.addSubview(vcCats.view);

P.S. don't forget to call 'removeFromParentViewController' before removing your sub view (like below):

@IBAction func onCanceled(_ sender: Any) {
    self.removeFromParentViewController()
    self.view.removeFromSuperview()
}
like image 3
Mostafa Aghajani Avatar answered Oct 22 '22 08:10

Mostafa Aghajani