UA-17470720-3

Jump to content


Photo
- - - - -

SCCustomCell with UIImageVIew that flashes when returning from detail view


  • Please log in to reply
6 replies to this topic

#1 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 14 November 2013 - 10:38 AM

Hi all,

 

I have a CoreData entity Entity, which has attributes of name and photo. These are shown in a SCCustomCell, and if the user hasn't selected a photo then a default icon is shown. Here's the viewDidLoad:

 

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationBarType = SCNavigationBarTypeAddLeftEditRight;
    
    NSManagedObjectContext *managedObjectContext = [(id)[UIApplication sharedApplication].delegate managedObjectContext];

    SCEntityDefinition *entityDefinition = [SCEntityDefinition definitionWithEntityName:@"Entity" managedObjectContext:managedObjectContext propertyNamesString:@"name;photo"];


    SCPropertyDefinition *photoPropertyDefinition = [entityDefinition propertyDefinitionWithName:@"photo"];
    photoPropertyDefinition.type = SCPropertyTypeImagePicker;

    photoPropertyDefinition.cellActions.willConfigure = ^(SCTableViewCell *cell, NSIndexPath *indexPath) {
        SCImagePickerCell *imagePickerCell = (SCImagePickerCell *)cell;
        imagePickerCell.displayImageNameAsCellText = NO;
        imagePickerCell.displayClearImageButtonInDetailView = TRUE;
        imagePickerCell.imagePickerController.allowsEditing = YES;
    };


    SCArrayOfObjectsSection *arrayOfObjectsSection = [SCArrayOfObjectsSection sectionWithHeaderTitle:nil entityDefinition:entityDefinition];
    arrayOfObjectsSection.addButtonItem = self.addButton;

    arrayOfObjectsSection.sectionActions.cellForRowAtIndexPath = ^SCCustomCell*(SCArrayOfItemsSection *itemsSection, NSIndexPath *indexPath) {
        NSLog(@"%i",indexPath.row);
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:@"2:name" nibName:@"TableViewCell"];

        Entity *entity = (Entity *)[itemsSection.items objectAtIndex:indexPath.row];
        UIImage *image;

        if  (entity.photo) {
            NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
            image = [UIImage imageWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:entity.photo]];
        }
        else {
            image = [UIImage imageNamed:@"dgApps.png"];
        }

        UIImageView *imageView = (UIImageView*)[customCell viewWithTag:1];

        imageView.image= image;

        return customCell;
    };
    
    
    [self.tableViewModel addSection:arrayOfObjectsSection];
}

 

That all works as expected. But the problem is that as you return from the detail view the imageView flashes. How do I stop that flash?

 

I've tried doing the 

 

 

if  (entity.photo) {
  // stuff
}
else {
  // other stuff
}

bit in various places, as above in the sectionActions.cellForRowAtIndexPath, also in the cellActions.willConfigure and cellActions.willDisplay, but the imageView still flashes.

 

If I select a cell with indexPath.row of 2, and then tap Done in it's detail view,  it looks like STV is calling sectionActions.cellForRowAtIndexPath for all the visible rows (which includes row 2) and then calls row 2 again. I think it's this second call of cellForRowAtIndexPath for row 2 that's causing the flash, but I can't work out how to stop it.

 

I also thought it might be something to do with the caching of imageNamed versus the non caching of imageWithContentsOfFile as imageNamed images don't flash as badly as the imageWithContentsOfFile images, so I wrote a category on UIImage that cached imageWithContentsOfFile using NSCache, but that didn't help either.

 

 

Any suggestions are most welcome.

 

 

 

 


Cheers,

Dave

www.dgapps.ie

#2 ozie

ozie

    ¯\_(ツ)_/¯

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 526 posts
  • LocationAustralia
Reputation: 169
Popular

Posted 15 November 2013 - 12:01 AM

yeah cellForRowAtIndexPath is called all the time for all visible rows..

it might be when the row is visible again it might be having its deselect being called at the same time and that might make the image flash

 

easy test would be to config the cell to cell.selectionStyle = UITableViewCellSelectionStyleNone;

that way can test if its flashing coz of the tableivew deselecting it


P.S. I hate Swift.. don't talk Swift.. Too old school to learn yet another programming language.


#3 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 15 November 2013 - 04:46 AM

Hi ozie,
 
Thanks for the suggestion. If I do 

cell.selectionStyle = UITableViewCellSelectionStyleNone;

that indeed stops the cell flashing when selected, and on the return the deselect flash, but the image still flashes. cell.selectionStyle has to go in the cellActions.willConfigure, doesn't work in sectionActions.cellForRowAtIndexPath just in case anyone else is wanting to set UITableViewCellSelectionStyleNone.
 
 
I've now stripped it back even further, so that the image is in the XIB and the code is just:
 

- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationBarType = SCNavigationBarTypeAddLeftEditRight;
    
    NSManagedObjectContext *managedObjectContext = [(id)[UIApplication sharedApplication].delegate managedObjectContext];

    SCEntityDefinition *entityDefinition = [SCEntityDefinition definitionWithEntityName:@"Entity" managedObjectContext:managedObjectContext propertyNamesString:@"name"];

    SCArrayOfObjectsSection *arrayOfObjectsSection = [SCArrayOfObjectsSection sectionWithHeaderTitle:nil entityDefinition:entityDefinition];
    arrayOfObjectsSection.addButtonItem = self.addButton;

    arrayOfObjectsSection.sectionActions.cellForRowAtIndexPath = ^SCCustomCell*(SCArrayOfItemsSection *itemsSection, NSIndexPath *indexPath) {
        NSLog(@"cellForRowAtIndexPath:%i",indexPath.row);
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:@"2:name" nibName:@"TableViewCell"];
        return customCell;
    };


    arrayOfObjectsSection.cellActions.willConfigure =  ^(SCTableViewCell *cell, NSIndexPath *indexPath) {
          cell.selectionStyle = UITableViewCellSelectionStyleNone;
    };

    [self.tableViewModel addSection:arrayOfObjectsSection];
}

And still the image flashes on returning from the detail view :-(

 

If I have 7 cells on screen, 0 to 6, and select cell 3, and then tap Done in cells 3 detail view the log says:

 

 

2013-11-15 12:07:56.671 STVCoreData[384:60b] cellForRowAtIndexPath:0
2013-11-15 12:07:56.679 STVCoreData[384:60b] cellForRowAtIndexPath:1
2013-11-15 12:07:56.686 STVCoreData[384:60b] cellForRowAtIndexPath:2
2013-11-15 12:07:56.693 STVCoreData[384:60b] cellForRowAtIndexPath:3
2013-11-15 12:07:56.702 STVCoreData[384:60b] cellForRowAtIndexPath:4
2013-11-15 12:07:56.708 STVCoreData[384:60b] cellForRowAtIndexPath:5
2013-11-15 12:07:56.715 STVCoreData[384:60b] cellForRowAtIndexPath:6
2013-11-15 12:07:56.724 STVCoreData[384:60b] cellForRowAtIndexPath:3

I think it's that second call of cellForRowAtIndexPath for row 3 that is causing the flash, but I'm not sure I can stop the second call, and even if I did, if I'm setting the image programatically then the image will be null at the beginning of the second call of cellForRowAtIndexPath so nothing will be displayed.

 

I think I'm just going to live with the flash!


Cheers,

Dave

www.dgapps.ie

#4 ozie

ozie

    ¯\_(ツ)_/¯

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 526 posts
  • LocationAustralia
Reputation: 169
Popular

Posted 15 November 2013 - 05:00 AM

don't suppose you have STV Pro, and can debug the source code..

i have it, so maybe tomorrow i might have a look if i have something that i can call to test the code to see why there is a second call


P.S. I hate Swift.. don't talk Swift.. Too old school to learn yet another programming language.


#5 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 15 November 2013 - 05:08 AM

I do have STV Pro. I'll have a look and see what I can find...


Cheers,

Dave

www.dgapps.ie

#6 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 19 November 2013 - 04:56 AM

I've done a bit more investigation around the flashing issue, here are some findings:
 
Standard Apple UITableView code doesn't call cellForRowAtIndexPath: when returning from a detail view. And images in the cells don't flash.
 
Using the code above, if I have only one entity, select the entity, tap done in the detail view, cellForRowAtIndexPath:0 is called, and the image flashes. Selecting the entity a second time, and done in the detail view, cellForRowAtIndexPath is NOT called, but the image still flashes :-(  So my original thought that it was the second call of the sectionAction.cellForRowAtIndexPath that was causing the flash was wrong.
 
 
I linked my example project to the STV source code, as per the PDF book. To get it to build I had to remark out #import "SCLicenseEngine.h" in SCGlobals.h, and then I had to build SensibleTableView target, and then the STV+CoreData target, and then my own project target. In that order. Is that normal? I thought that building my target would automatically build the linked targets. No? Changes in STV are included in the build when I rebuild my project, so that bit seems to work. Just the initial build is a bit long winded. Anyway….
 
 
So I've been looking through the STV code for hours, days now! Friday afternoon, Monday all day, and this morning, Tuesday. Finally I've found the line causing the image to flash!!!! 
 
In SCTableViewSection there is a method itemModified: that is called when Done is tapped in a detail view, but it's not called when Cancel is tapped.
 
In itemModified: there's a reloadRowsAtIndexPaths: withRowAnimation: on the ownerTableViewModel.tableView which causes the cell (obviously) to reload.

The row animation is UITableViewRowAnimationAutomatic.

Changing that to UITableViewRowAnimationNone and no image flash! Hurrah!!!

 

I now have questions about the best way to use edited STV code, but I'll save that for another topic...


  • sminar likes this
Cheers,

Dave

www.dgapps.ie

#7 ozie

ozie

    ¯\_(ツ)_/¯

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 526 posts
  • LocationAustralia
Reputation: 169
Popular

Posted 26 January 2014 - 08:58 PM

after playing with my app today, i noticed that when using cellForRowAtIndexPath, this gets called a lot.. and i am a lot.. which might be why its flashing.

to reduce the number of called 99% i noticed that using the customHeightForRowAtIndexPath stopped STV from having to use its internal methods of working out cell height (which by default it uses 100 rows to work out the height, and thankfully there is an option to set how many to use)  


P.S. I hate Swift.. don't talk Swift.. Too old school to learn yet another programming language.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users