I've looked at a ton of posts on similar things, but none of them quite match or fix this issue. Since iOS 7, whenever I add a UIButton
to a UITableViewCell
or even to the footerview it works "fine", meaning it receives the target action, but it doesn't show the little highlight that normally happens as you tap a UIButton
. It makes the UI look funky not showing the button react to touch.
I'm pretty sure this counts as a bug in iOS7, but has anyone found a solution or could help me find one :)
Edit: I forgot to mention that it will highlight if I long hold on the button, but not a quick tap like it does if just added to a standard view.
Code:
Creating the button:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.titleLabel.font = [UIFont systemFontOfSize:14];
button.titleLabel.textColor = [UIColor blueColor];
[button setTitle:@"Testing" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchDown];
button.frame = CGRectMake(0, 0, self.view.frame.size.width/2, 40);
Things I've Tested:
//Removing gesture recognizers on UITableView
in case they were getting in the way.
for (UIGestureRecognizer *recognizer in self.tableView.gestureRecognizers) {
recognizer.enabled = NO;
}
//Removing gestures from the Cell
for (UIGestureRecognizer *recognizer in self.contentView.gestureRecognizers) {
recognizer.enabled = NO;
}
//This shows the little light touch, but this isn't the desired look
button.showsTouchWhenHighlighted = YES;
What I did to solve the problem was a category of UIButton using the following code :
the button reacts correctly when I press on it in a UITableViewCell, and my UITableView behaves normally as the
delaysContentTouches
isn't forced.I tried to add this to the accepted answer but it never went through. This is a much safer way of turning off the cells delaysContentTouches property as it does not look for a specific class, but rather anything that responds to the selector.
In Cell:
In TableView:
Since iOS 8 we need to apply the same technique to UITableView subviews (table contains a hidden UITableViewWrapperView scroll view). There is no need iterate UITableViewCell subviews anymore.
This answer should be linked with this question.
Solution in Swift, iOS8 only (needs the extra work on each of the cells for iOS7):
To use, all you have to do is change the class to
NoDelayTableView
in your storyboard.I can confirm that in iOS8, buttons placed inside a contentView in a cell now highlight instantly.
Since objc is dynamic, and scrollView is the only class that responds to delaysContentTouches, this should work for both ios 7 and 8 (put it somewhere early in your tableViewController, like awakeFromNib):
You may also have to turn off "delaysContentTouches" in your storyboard or nib by selecting the table inside your viewController. BTW, this might not work on ios 7 if you're using a tableView inside a viewController, at least I couldn't get it to work.