20

I have a custom button where the image changes upon a press. This button is in the contentView of a UITableViewCell within a UITableView.

There is a noticeable delay when pressing the button before the image changes. Take the button out of the cell and into a UIView the change of image on press is instant.

How do I remove this delay?

It's worth pointing out that I have tried setting delaysContentTouches on the UITableView but it makes no difference that I can see.

Here is some test code that proves the issue. Create new project and add a UITableView to the storyboard.

#import "JWViewController.h"

@implementation JWViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.delaysContentTouches = NO;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; }
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return return 65.0f; }

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] init];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"apple"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"apple_selected"] forState:UIControlStateHighlighted];
    button.frame = CGRectMake(0, 0, 65, 65);
    [cell.contentView addSubview:button];
    return cell;
}

@end

I have searched and there appears to be a number of other posts relating to this but none with a working answer.

This blog post doesn't appear to work either in this simple case.

Community
  • 1
  • 1
JMWhittaker
  • 3,633
  • 3
  • 23
  • 30

4 Answers4

1

Finally got solution of your issue.

Try this, it will work fine. Add steps in your existing code:- 1.) Set tag of the button which is in content view. 2.) Add target on that button.

- (void)viewDidLoad
    {
        [super viewDidLoad];
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
        self.tableView.delaysContentTouches = NO;
    }

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; }
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 65.0f; }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [[UITableViewCell alloc] init];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setImage:[UIImage imageNamed:@"apple.jpg"] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"apple_selected.png"] forState:UIControlStateHighlighted];
        button.frame = CGRectMake(0, 0, 65, 65);
        button.tag = indexPath.row;
        [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventAllTouchEvents];
        [cell.contentView addSubview:button];
        return cell;
    }

    - (void)buttonPressed:(UIButton *)sender
    {
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sender.tag inSection:0]];

        for (UIView *currentView in cell.subviews)
        {
            if ([NSStringFromClass([currentView class]) isEqualToString:@"UITableViewCellScrollView"])
            {
                UIScrollView *svTemp = (UIScrollView *) currentView;
                [svTemp setDelaysContentTouches:NO];
                break;
            }
        }
    }
  • This code is weird and redundant. Your `buttonPressed:` method will get called a ton of times, because you are using `UIControlEventAllTouchEvents` control event. Better to loop through your subviews in `tableView:cellForRowAtIndexPath:`. I was able to use this as a starting point and add the following to my `UITableViewCell` subclass (in a setup method): `if ([self.superview respondsToSelector:@selector(setDelaysContentTouches:)]) { UIScrollView *svTemp = (UIScrollView *)self.superview; [svTemp setDelaysContentTouches:NO]; }` – livingtech Dec 01 '14 at 23:01
0

I was able to fix using this solution: https://stackoverflow.com/a/29259705/1728552

Seems that the table view has another scrollview inside.

Community
  • 1
  • 1
Serluca
  • 2,102
  • 2
  • 19
  • 31
-1

Subclass UITableView, and implement only this method:

- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
    return YES;
}

Then set tableView.delaysContentTouches = NO;

Srikanth
  • 1,861
  • 17
  • 29
-2

You need to pass the touch event directly to the button.

 [yourTableViewObject setDelaysContentTouches:NO];

This disables scrolling of the table view when the button is touched. you can handle that by either using a Gesture recogniser or subclassing the tableview to implement

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
return YES;
}