6

I have a custom UITableViewCell with 7 subviews. One of them is an activity view, so in order to find it and stop, I do something like this:

NSArray *subviews=[cell subviews];       
NSLog(@"Subviews count: %d",subviews.count);     
for (UIView *view in subviews)  
{                
  NSLog(@"CLASS: %@",[view class]);     
  // code here     
 }

In iOS6 , Subviews count: is 7 and one of them is the activity view. But in iOS7 , the Subviews count: is 1 and [view class] returns UITableViewCellScrollView . Tried, NSArray *subviews=[cell.superview subviews]; and NSArray *subviews=[cell.contentview subviews]; , but in vain.

Any suggestions?

DD_
  • 7,230
  • 11
  • 38
  • 59
  • 4
    Recursing subviews is a pain, you should consider subclassing `UITableViewCell` or using `viewWithTag:` to find the activity view. https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html#//apple_ref/occ/instm/UIView/viewWithTag: – Brian Nickel Oct 04 '13 at 05:31

5 Answers5

13

You need to recursively descend into each subview's subviews and so on. Never make any assumptions about the private subview structure. Better yet, since you should only add subviews to the cell's contentView, just look in the contentView, not the whole cell.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • In additions to the answer, here is example: http://stackoverflow.com/a/19412487/1721946 – Lunf Nov 19 '13 at 16:56
  • 1
    After looking through Apple's documentation I agree with Brian Nickel you should use the `[contentView viewWithTag:tag]` instead of recursively iterating through views. Search for viewWithTag: [here](https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/TableViewCells/TableViewCells.html) to see an explanation – derickito Dec 03 '14 at 05:40
1

I think you should add a conditional statement to your code:

NSArray *subviews;
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
    subviews = aCell.contentView.subviews;
else
    subviews = aCell.subviews;

for(id aView in subviews) {
    if([aView isKindOfClass:[aField class]]) {
        //your code here
    }
}

//don't forget to add a conditional statement even on adding your subviews to cell
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
    [aCell.contentView addSubview:aField];
else
    [aCell addSubview:aField];

This is the define for the above SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO macro:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
valvoline
  • 7,737
  • 3
  • 47
  • 52
  • 2
    I don't think this is actually necessary, as contentView has been there since iOS2: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/contentView – Caesium Dec 30 '13 at 03:44
1

I was adding imageview dynamically on cell so for self.contentview.subviews was removing the separator line and accessory view. So I did is something like

for (id obj in self.contentView.superview.subviews) {
    if ([obj isMemberOfClass:[UIImageView class]]) {
        [obj removeFromSuperview];
    }
}

worked for me, hope for few people it will work!

Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75
0

Here is how one can iterate through controls inside a Custom UITableViewCell

UITableViewCell *cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault       reuseIdentifier:@"anyname"];


   UIView *view=cell.contentView;

    for(id object in view.subviews)
    {

        if([object isKindOfClass:[UILabel class]])
        {
            NSLog(@"%@",[object class]);
            // UILabel *label=  (UILabel*)view;
            //[label setFont:TextFont];
        }



    }

You can check for any sort of control based upon class of that particular control.

Husrat Mehmood
  • 2,270
  • 1
  • 20
  • 22
0

Since I haven't seen then correct answer to this question I'll posted here even if this is a year old. (Credit to Brian Nickel who already posted about this). First of all you're only getting one view because cell have a contentView where all it's childs live (this much has already been explained). As to how to find your view inside the contentView, in this documentation from Apple https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/TableViewCells/TableViewCells.html you can see that they recommend to use viewWithTag: to get views inside of a content view. So you need to tag each view in your content view or only the ones you want to find and then call: [cell.contentView viewWithTag: tag] Hope that helps any googlers like me.

derickito
  • 695
  • 7
  • 25