UA-17470720-3

Jump to content


Photo
- - - - -

Having an issue mixing in custom table view cells


  • Please log in to reply
3 replies to this topic

#1 rickbdotcom

rickbdotcom

    Jr. Member

  • STV 5.0 Pro
  • PipPip
  • 13 posts
Reputation: 4
Good

Posted 30 May 2015 - 09:57 PM

I just started using Sensible Cocoa and I'm having an issue with mixing in custom cells into a SCTableViewController  using a tableview with static cells. I have some custom table view cells in just a regular old table view section which contain UIButtons. I hooked up the target of the buttons to the view controller but the actions never get called when the button is pressed. 

 

I managed to track down the cause of the issue by creating a custom UIButton and overriding various methods to figure out what was going on. It looks like the SCTableViewController instantiates a new copy of every static cell and when it does this the buttons lose their targets through the archive/unarchiving process that you typically have to do to make a copy of a UIView object.

 

The call stack looks like this when a new copy of the button (a custom class called WTF in this case :). Is there anything I can do about this? Also note in IB the cells are *not* SCCustomCell just normal UITableViewCell's I want in the table with some buttons.

 

#0 0x000000010e4f4bbb in -[WTF initWithCoder:] 
#1 0x0000000110c7c584 in _decodeObjectBinary ()
#2 0x0000000110c7d587 in -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:] ()
#3 0x0000000110c7d789 in -[NSArray(NSArray) initWithCoder:] ()
#4 0x0000000110c7c584 in _decodeObjectBinary ()
#5 0x0000000110c7b8da in _decodeObject ()
#6 0x000000010f0d1050 in -[UIView initWithCoder:] ()
#7 0x000000010f4d40f7 in -[UITableViewCellContentView initWithCoder:] ()
#8 0x0000000110c7c584 in _decodeObjectBinary ()
#9 0x0000000110c7d587 in -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:] ()
#10 0x0000000110c7d789 in -[NSArray(NSArray) initWithCoder:] ()
#11 0x0000000110c7c584 in _decodeObjectBinary ()
#12 0x0000000110c7b8da in _decodeObject ()
#13 0x000000010f0d1050 in -[UIView initWithCoder:] ()
#14 0x000000010f30772f in -[UITableViewCell initWithCoder:] ()
#15 0x000000010e5778b9 in -[SCTableViewCell initWithCoder:] at /Users/tarekskr/SensibleCocoa/SensibleTableView/STV4.0/Dynamic Frameworks/SensibleTableView/SensibleTableView/STV-Core/SCTableViewCell.m:172
#16 0x000000010e57e38f in -[SCCustomCell initWithCoder:] at /Users/tarekskr/SensibleCocoa/SensibleTableView/STV4.0/Dynamic Frameworks/SensibleTableView/SensibleTableView/STV-Core/SCTableViewCell.m:1350
#17 0x0000000110c7c584 in _decodeObjectBinary ()
#18 0x0000000110c7b8da in _decodeObject ()
#19 0x0000000110c9e971 in +[NSKeyedUnarchiver unarchiveObjectWithData:] ()
#20 0x000000010e577612 in +[SCTableViewCell cellWithCell:] at /Users/tarekskr/SensibleCocoa/SensibleTableView/STV4.0/Dynamic Frameworks/SensibleTableView/SensibleTableView/STV-Core/SCTableViewCell.m:133
#21 0x000000010e5b7c70 in -[SCTableViewController addStaticContentToModel] at /Users/tarekskr/SensibleCocoa/SensibleTableView/STV4.0/Dynamic Frameworks/SensibleTableView/SensibleTableView/STV-Core/SCTableViewController.m:653
#22 0x000000010e5b6b4c in -[SCTableViewController loadView] at /Users/tarekskr/SensibleCocoa/SensibleTableView/STV4.0/Dynamic Frameworks/SensibleTableView/SensibleTableView/STV-Core/SCTableViewController.m:296
#23 0x000000010f19df79 in -[UIViewController loadViewIfRequired] ()
 
For now, I think I may try to swizzle + (instancetype)cellWithCell:(UITableViewCell *)cell; and try to hook back up the missing action target.

Edited by rickbdotcom, 30 May 2015 - 10:04 PM.


#2 rickbdotcom

rickbdotcom

    Jr. Member

  • STV 5.0 Pro
  • PipPip
  • 13 posts
Reputation: 4
Good

Posted 30 May 2015 - 11:09 PM

Well swizzling solved my problem for now. :) Hopefully you guys can incorporate something like this into the library itself.

 

@implementation SCTableViewCell(TargetFix)

 

+(void)targetFix

{

NSError* error = nil;

[self jr_swizzleClassMethod:@selector(cellWithCell:) withClassMethod:@selector(cellWithCell_TargetFix:) error:&error];

}

 

+(void)restoreControlTargetsFromView:(UIView*)origView toView:(UIView*)newView

{

if([origView isKindOfClass:[UIControl class]])

{

UIControl* oc =(id)origView;

UIControl* nc =(id)newView;

for(id target in oc.allTargets)

{

// UIControlEventTouchUpInside is all I really care about at the moment. We could iterate over all possible UIControlEvents here

for(NSString* action in [oc actionsForTarget:target forControlEvent:UIControlEventTouchUpInside])

{

[nc addTarget:target action:NSSelectorFromString(action) forControlEvents:UIControlEventTouchUpInside];

}

}

}

NSEnumerator* oenum = origView.subviews.objectEnumerator;

NSEnumerator* nenum = newView.subviews.objectEnumerator;

UIView *ov, *nv;

while((ov = [oenum nextObject]) && (nv = [nenum nextObject]))

{

[self restoreControlTargetsFromView:ov toView:nv];

}

}

 

+ (instancetype)cellWithCell_TargetFix:(UITableViewCell *)cell

{

UITableViewCell* newCell = [self cellWithCell_TargetFix:cell];

[self restoreControlTargetsFromView:cell.contentView toView:newCell.contentView];

return (id)newCell;

}

 

@end


  • Tarek likes this

#3 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 02 June 2015 - 09:17 AM

Hi Rick,

 

Thanks a lot for reporting this, we'll be fixing that ASAP.  Awesome work swizzling that in BTW!! ;)



#4 rickbdotcom

rickbdotcom

    Jr. Member

  • STV 5.0 Pro
  • PipPip
  • 13 posts
Reputation: 4
Good

Posted 03 June 2015 - 11:18 PM

Awesome, glad I could help. Thanks!






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users