1

I am trying to implement a 'SETTINGS page' like split view with a table view on the left and an image view on the right. Everything is fine but there is a delay in table view cell touch if try to tap it faster. DidSelectRowAtIndex path is not getting called but the cell blinks.

What I've tried,

  1. moved image changing logic into willSelectRowAtIndexPath from DidSelectRowAtIndex

  2. removed everything from delegate methods (to check whether is it due to loading of image)

How can I solve this wired problem?

TableDatasource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier = @"tutorialCell";
        CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (cell == nil) {
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TutorialTableCell" owner:nil options:nil];
            cell = [nib objectAtIndex:0];        
        }
        NSDictionary * dic = [dictArray objectAtIndex:indexPath.row];
        cell.tutorialText.text = [dic valueForKey:TUTORIAL_TEXT];
        cell.tutorialImage.image = [UIImage imageNamed:[dic valueForKey:TUTORIAL_ICON]];
        cell.contentView.backgroundColor = [UIColor colorWithHex:@"#36393D" alpha:1.0];
        UIView *bgColorView = [[UIView alloc] init];
        [bgColorView setBackgroundColor:[UIColor colorWithHex:@"#1f1f1f" alpha:1.0]];
        [cell setSelectedBackgroundView:bgColorView];
        return cell;
    }

TableView Delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary * dic = [dictArray objectAtIndex:indexPath.row];
    _tutorialImageView.image = [UIImage imageNamed:[dic valueForKey:TUTORIAL_IMAGE]];
}
Clement Prem
  • 3,112
  • 2
  • 23
  • 43

2 Answers2

2

UITableViews are subclasses of UIScrollViews which have delaysContentTouches enabled by default. This is because the UIScrollView tries to figure out if the touch is part of a swipe gesture or scrolling action before allowing the touch to go to its subviews. If you really want to disable that action you can, by setting the delaysContentTouches of your table view to NO. This might make scrolling behave a little strangely because taps will immediately go to your table view's cells. You might find that you actually like the delayed touch action better than the non-delayed touch action.

Edit Clement says he already tried that, so here's another idea.

In the posted code you're loading these images from disk (imageNamed:) at least initially. UIKit might do some caching. If your tutorial images are pretty big there might not be much you can do to load them faster, so load them ahead of time instead. You can load all the images and put them in a dictionary using those same [dic valueForKey:TUTORIAL_IMAGE] keys. Then in tableView:didSelectRowAtIndexPath: you can set _tutorialImageView.image to one of the (already loaded) images from the dictionary.

Aaron Golden
  • 7,092
  • 1
  • 25
  • 31
  • It is already set to NO in the interface builder, I even tried putting it inside 'viewdidload' but no changes in the behaviour. – Clement Prem Mar 25 '13 at 06:38
  • @Clement OK, new suggestion in edit. Also, have you tried profiling this code with Instruments? If it really is a performance issue it would help to know the heaviest backtrace. – Aaron Golden Mar 25 '13 at 06:51
  • Thank you. Ill try your suggestions – Clement Prem Mar 25 '13 at 07:14
  • it appears the individual contentViews have their own UIScrollView, which the tableView's delaysContentTouches does not affect and you must set per cell. – aehlke Mar 12 '14 at 05:05
0

It's probably the image loading code. I have two suggestions here:

a. If the images are not too many, you could load them all and cache them in an NSArray for example.

b. If memory is a concern, I suggest first displaying a placeholder image and/or a UIActivityIndicator, then load the main image in a separate thread off the main thread.

Matt
  • 2,391
  • 2
  • 17
  • 18