I've placed a UIButton inside a custom UIView, CustomButtonView. The UIButton is not responding to tap/click events, and its appropriate selector method is not being triggered. Here's my code below; what have I done wrong?
As well, the custom view has a background color of red. When I add the custom view to my view controller's view, the red rectangle displays. However, when I add my UIButton to my custom view (with the background color of red), only the UIButton displays, not the red rectangle. Why is this happening?
//
// CustomButtonView.h
//
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CustomButtonView : UIView
@property (strong, nonatomic) UIImageView *buttonImageView;
@property (strong, nonatomic) UIButton *button;
@end
NS_ASSUME_NONNULL_END
//
// CustomButtonView.m
//
#import "CustomButtonView.h"
@implementation CustomButtonView
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor redColor];
_button = [UIButton buttonWithType:UIButtonTypeSystem];
_button.backgroundColor = [UIColor greenColor];
[_button setTitle:@"john doe" forState:UIControlStateNormal];
[_button setTitle:@"john doe" forState:UIControlStateHighlighted];
_button.translatesAutoresizingMaskIntoConstraints = NO;
_button.titleLabel.font = [UIFont boldSystemFontOfSize:14.0];
_button.titleLabel.textColor = [UIColor whiteColor];
self.userInteractionEnabled = NO;
self.button.userInteractionEnabled = YES;
//[self addSubview:_button];
//[_button.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES;
//[_button.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = YES;
}
return self;
}
@end
//
// ViewController.m
// TestApp
//
//
#import "ViewController.h"
#import "CustomButtonView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor yellowColor];
_customButtonView = [[CustomButtonView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_customButtonView.backgroundColor = [UIColor redColor];
_customButtonView.translatesAutoresizingMaskIntoConstraints = NO;
[_customButtonView.button addTarget:self action:@selector(customButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_customButtonView];
}
- (void)customButtonTapped:(id)sender{
NSLog(@"Button tapped!");
}
@end
Here are some screenshots, below. Please click on the links.
CodePudding user response:
When you disable user interaction for a specific view then this user interaction is not forwarded to its subviews. Or in other words; for user interaction to work you need to make sure that all superviews in chain (superview of superview of superview) do have user interaction enabled.
In your case you have self.userInteractionEnabled = NO;
which means that any subview of self
(including your button) will not accept any user interaction.
Next to this issues it is still possible that other issues are present. For instance: A subview will accept user interaction only within physical area of all of its superviews. That means that if a button with frame { 0, 0, 100, 100 }
is placed on a superview of size { 100, 50 }
then only the top part of the button will be clickable.
As for the size changes this is a completely different story...
You decided to disable translation of autoresizing mask on your custom view by writing _customButtonView.translatesAutoresizingMaskIntoConstraints = NO;
. That means that you will not use frame
in conjunction with other constraints. It means that whatever frame you set (in your case CGRectMake(0, 0, 100, 100)
) this frame will be overridden by anything else that may effect the frame of your custom view.
In case where your button code is commented out there is no such thing that "may effect the frame of your custom view" and the view stays as size of { 100, 100 }
. But as soon as you added a button you added additional constraints which most likely lead to resizing your button to sizeToFit
and with it its superview which is your custom view.
To avoid this you need to either remove disabling of translation of autoresizing mask into constraint on your custom view. Or you need to define custom view size by adding constraints to it so that they are set to { 100, 100 }
. You can simply constrain heightAnchor
and widthAnchor
to 100
.