1

My UIButton doesn't respond. I think it is behind the UIView or that it is not the first responder. I made a custom view which subclass is MKAnnotationView. Maybe this is a part of the problem. I also tried to use userInteractionEnabled, but no luck. Anyone had the same issue?

- (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier{   
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];

// Create selected and un-selected pin images
_normalPin = [UIImage imageNamed:@"map_pin.png"];
_selectedPin = [UIImage imageNamed:@"selected_map_pin.png"];

// Set current pin to unselected image
self.image = _normalPin;

// cast annotation an our expected BLAnnotation

Annotation *blAnnotation = (Annotation *)annotation;

// create title label and size to text

_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 280, 20)];
_titleLabel.text = blAnnotation.title;
_titleLabel.textAlignment = UITextAlignmentLeft;
_titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:13];
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.shadowColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.7];
_titleLabel.shadowOffset = CGSizeMake(0, -1.0);
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.lineBreakMode = UILineBreakModeWordWrap;
_titleLabel.numberOfLines = 3;

CGSize titleLabelSize = [blAnnotation.title sizeWithFont: _titleLabel.font constrainedToSize: CGSizeMake(280, 600) lineBreakMode: _titleLabel.lineBreakMode];
_titleLabel.frame = CGRectMake(_titleLabel.frame.origin.x, _titleLabel.frame.origin.y, 280, titleLabelSize.height);

// create subtitle label and size to text

_subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, _titleLabel.frame.size.height + 8, 280, 20)];
_subtitleLabel.text = blAnnotation.subtitle;
_subtitleLabel.textAlignment = UITextAlignmentLeft;
_subtitleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:11];
_subtitleLabel.textColor = [UIColor whiteColor];
_subtitleLabel.shadowColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.7];
_subtitleLabel.shadowOffset = CGSizeMake(0, -1.0);
_subtitleLabel.backgroundColor = [UIColor clearColor];
_subtitleLabel.lineBreakMode = UILineBreakModeWordWrap;
_subtitleLabel.numberOfLines = 4;

CGSize subtitleLabelSize = [blAnnotation.subtitle sizeWithFont: _subtitleLabel.font constrainedToSize: CGSizeMake(235, 600) lineBreakMode: _subtitleLabel.lineBreakMode];
_subtitleLabel.frame = CGRectMake(_subtitleLabel.frame.origin.x, _subtitleLabel.frame.origin.y, subtitleLabelSize.width, subtitleLabelSize.height);

// create custom button
_infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
_infoButton.frame = CGRectMake(0, _titleLabel.frame.size.height + _subtitleLabel.frame.size.height + 80, 175, 50);
//_infoButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
//_infoButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

//[_infoButton setImage:[UIImage imageNamed:@"more_info.png"] forState:UIControlStateNormal];
[_infoButton addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];

// create callout view to be shown once a annotation view is selected

_calloutView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, _titleLabel.frame.size.height + _subtitleLabel.frame.size.height + _infoButton.frame.size.height + 5)];
_calloutView.hidden = YES;
_calloutView.userInteractionEnabled = YES;
[self addSubview:_calloutView];

// create rounded rect background and size to text

UIImageView *backgroundRect = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, _calloutView.frame.size.width, _calloutView.frame.size.height)];
//[backgroundRect setAlpha:0.8];
//[backgroundRect setOpaque:NO];
[backgroundRect.image drawInRect:_calloutView.frame];

UIGraphicsBeginImageContext(backgroundRect.frame.size);

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect frame = _calloutView.bounds;
[[UIColor colorWithRed:.2 green:.2 blue:.2 alpha:1] set];
CGPathRef roundedRectPath = [self roundedRectPath:frame radius:5];
CGContextAddPath(ctx, roundedRectPath);
CGContextFillPath(ctx);
CGPathRelease(roundedRectPath); 

backgroundRect.userInteractionEnabled = YES;
backgroundRect.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[_calloutView addSubview:backgroundRect];
[_calloutView addSubview:_titleLabel];
[_calloutView addSubview:_subtitleLabel];
[_calloutView addSubview:_infoButton];

// position callout above pin

_calloutView.frame = CGRectMake(-140, -_calloutView.frame.size.height+10, _calloutView.frame.size.width, _calloutView.frame.size.height);

backgroundRect = nil;

return self;

}

Ryan
  • 39
  • 4

2 Answers2

1

My guess is that your button is pointing to itself as the target. If the button is not the first responder and it is tapped, its target function is not called in the above scenario. I fixed my similar issue by using lazy var to declare the UIButton in Swift 4 Xcode 9, pointing the target to the parent view / view controller.

// Sets target to parent view or view controller
// someFunction is called even if the button is not the first responder when tapped
lazy var nextCreateButton: UIButton = {
    let button = UIButton(type: .system)
    button.addTarget(self, action: #selector(someFunction), for: .touchUpInside)
    return button
}()

// Sets target to the button itself
// someFunction is not called when the button is not the first responder
let nextCreateButton: UIButton = {
    let button = UIButton(type: .system)
    button.addTarget(self, action: #selector(someFunction), for: .touchUpInside)
    return button
}()
Sanzio Angeli
  • 2,872
  • 1
  • 16
  • 30
0

Try using [self addSubview:_calloutView] after you add your button and your lables to *_calloutView* as subviews, not before.

Let me know how it turns out

Eren Beşel
  • 1,047
  • 8
  • 16
  • Thanks for your answer, but this didn't fix the problem. – Ryan Mar 16 '12 at 13:19
  • Alright then, would you explain a bit more about your button not responding? Is it untouchable, can you see it on the screen? – Eren Beşel Mar 18 '12 at 19:06
  • I can see it on the screen, but it is not touchable. So I think that it is hiding behind something. – Ryan Mar 19 '12 at 07:48