Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton not showing highlight on tap in iOS7

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;
like image 534
Eric Avatar asked Oct 08 '13 19:10

Eric


3 Answers

In that tableview you just add this property.

tableview.delaysContentTouches = NO;

And add in cellForRowAtIndexPath after you initiate the cell you just add below code. The structure of the cell is apparently different in iOS 6 and iOS 7.
iOS 7 we have one control UITableViewCellScrollView In between UITableViewCell and content View.

for (id obj in cell.subviews)
{
    if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"])
    {
        UIScrollView *scroll = (UIScrollView *) obj;
        scroll.delaysContentTouches = NO;
        break;
    }
}
like image 176
subramani Avatar answered Oct 23 '22 08:10

subramani


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.

for (UIView *currentView in tableView.subviews) {
    if ([currentView isKindOfClass:[UIScrollView class]]) {
        ((UIScrollView *)currentView).delaysContentTouches = NO;
        break;
    }
}

This answer should be linked with this question.

like image 40
Roman B. Avatar answered Oct 23 '22 07:10

Roman B.


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:

for (id obj in self.subviews) {
     if ([obj respondsToSelector:@selector(setDelaysContentTouches:)]) {
          [obj setDelaysContentTouches:NO];
     }
}

In TableView:

self.tableView.delaysContentTouches = NO;
like image 27
Eric Avatar answered Oct 23 '22 08:10

Eric