Managing events on a custom UIControl

13,069

Solution 1

I came up with a simple solution that doesn't need subclassing of the UIButton.

In the action method defined for the UIButton's TouchUpInside control event, I have added the following line of code:

[self sendActionsForControlEvents:UIControlEventTouchUpInside];

This results in the TouchUpInside control event being called, when clicking anywhere in the custom UIControl.

Solution 2

UIViews have a method called -hitTest:withEvent: that the event system uses to crawl the view hierarchy and dispatch events to subviews. If you want a parent view to gobble up all events that might otherwise be dispatched to its subviews, just override the parent's -hitTest:withEvent: with something like the following:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
  if(CGRectContainsPoint([self bounds], point)){
    return self;
  }
  return [super hitTest:point withEvent:event];
}
Share:
13,069
Beav
Author by

Beav

Updated on July 14, 2022

Comments

  • Beav
    Beav almost 2 years

    I am subclassing UIControl to compose a custom control that contains different standard controls.

    For this discussion let's assume that my custom UIControl contains a UIButton only.

    What I would like to achieve is that clicking anywhere in the custom UIControl generates a click event for that custom UIControl. The standard behavior is that the UIButton will process and consume (i.e. not forward) the click event.

    As subclassing UIButton is discouraged, I can't really find a straightforward way of achieving this.

    Any suggestions?

  • Beav
    Beav over 13 years
    UIButton is a class cluster, which tends to complicate things. Please refer to the first comment in the following question: stackoverflow.com/questions/2920045/…
  • Anomie
    Anomie over 13 years
    All that means is "don't try to use buttonWithType: with your custom subclass".
  • Beav
    Beav over 13 years
    I understand the purpose of userInteractionEnabled and addTarget:action:forControlEvents:. In fact I use this on the UIButton to process the TouchUpInside event. What I also want to do, however, is to forward the TouchUpInside event to the custom UIControl in which the button is positioned. In this way my custom control can trigger an action (e.g. hiding the keyboard) when clicked, regardless of whether the click was on the UIButton or elsewhere on the UIControl.
  • Beav
    Beav over 13 years
    So, if subclassing UIButton is an option, I guess I could overwrite the sendAction:to:forEvent: method, so it is called on the UIButton and forwarded to the custom UIControl.
  • Beav
    Beav over 13 years
    Just tried subclassing UIButton and ran into problems. Using IB I added my custom UIButton to my custom UIControl and gave it a button type of Rounded Rect. However, when running the app, it displays a custom button. As buttonType is read-only, I don't see a way of solving this in IB. Any suggestions?
  • Anomie
    Anomie over 13 years
    What exactly is wrong with having your custom control register for UIControlEventTouchUpInside on the button?
  • Beav
    Beav over 13 years
    Nothing is wrong with that. I just needed a way to also forward the event from there. I did this using sendActionsForControlEvents, which solved my problem.