Well... a UITableView
is a subclass of UIScrollView
and the UIScrollView
class is known to eat touches for it's own purpose.
When it realizes the touch was not meant for it, it passes it to it's immediate subview.
This feature is the delaysContentTouches
property (which by default is YES
).
Which is why, the UIButton
shows it's highlighted state only after a extended touch because the touch event was with the UITableView
for a short while until it determined whether the touch was meant for scrolling or swiping the cell and on realizing the touch was for neither, it immediately passes the touch event to the subView
directly below it.
In case of a quick-tap, the button's highlighted state is bypassed due to this delay and the target selector method is called directly.
To show the highlighted state of the button in a UITableView
(just as it would on a UIView
) do:
For iOS7+:
In -viewDidLoad
or anywhere appropriate do:
[yourTableViewObject setDelaysContentTouches:NO];
Also... The cell.subviews
has a class UITableViewCellScrollView
which apparently is another scrollView
and we need to disable the delaysContentTouches
property of this class as well.
So... in the -cellForRowAtIndexPath:
method (just before return cell;
) do:
NSArray *test = cell.subviews;
for (UIView *currentView in cell.subviews) {
if ([NSStringFromClass([currentView class]) isEqualToString:@"UITableViewCellScrollView"]) {
UIScrollView *svTemp = (UIScrollView *) currentView;
[svTemp setDelaysContentTouches:NO];
break;
}
}
For iOS 6-:
In iOS6, the cell.subviews
has a UITableViewCellContentView
class which is not a scrollView
subclass and so all it takes is setting one parameter for the tableView
alone.
So, in -viewDidLoad
or anywhere appropriate, this is all that you need:
[yourTableViewObject setDelaysContentTouches:NO];
PS: By doing this, it will mess up with the scrolling of the tableView
so use your better judgement.