Reputation: 29906
I have tried everything and a UIActivityMonitorView wont spin when I set in in didSelectRowForIndexPath. I access the custom tableview cell with
CustomCell *cell = (CustomCell *) [tableview cellForRowAtIndexPath];
I can see the cell and its properties initialized in the debugger but when I try modifying anything on the cell nothing changes. I set the cells activityMonitor IBOutlet to start spinning in a performSelectorAfterDelay woth no luck. When I try to set the cells alpha to 0 nothing happens either.
If, however I set the spinner to spin via IB it works when the cell loads up.
I also tried to access it via the tag, but it didnt work.
How does one set the properties on a custom tableview cell?
Upvotes: 0
Views: 184
Reputation: 438467
Check out Customizing Cells in the Table View Programming Guide. The specifics, though, vary between Storyboards, NIBs, or programmatically created UITableViewCell
cells. You have to share your tableView:cellForRowAtIndexPath:
and your tableView:didSelectRowAtIndexPath:
for us to diagnose what's going on. Below, I'll show you an example of using the spinning activity indicator, but there's nothing special going on here. I suspect that there's something simple going on with your app, but not something we can help you with unless we can see your code.
But, to show you an example, assuming you've subclassed UITableViewCell
with an interface defined in Interface Builder. Here is a sample didSelectRowAtIndexPath
that starts the spinning activity indicator, and turns it off 15 seconds later.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TestCell *cell = (TestCell *)[tableView cellForRowAtIndexPath:indexPath];
// I have a model in my app for the sections of the tableview, as well as the rows,
// so let's get the pointer to the appropriate model information. Your implementation
// may differ, but hopefully you get the idea.
Section *section = self.sections[indexPath.section];
Row *row = section.rows[indexPath.row];
// because we selected this row, start the activity indicator
[cell addActivityIndicator];
// let's flag the row in our model to indicate that we're busy here (so if and when
// we represent this row, we'll know if we're busy or not)
row.loading = YES;
// and let's asynchronously dispatch a "stop activity indicator" in 15 seconds
int64_t delayInSeconds = 15.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// because this is happening asynchronously, let's re-retrieve the cell
// pointer, just in case it might have scrolled off of the visible screen
// as is no longer visible or the pointer to the cell might have changed
TestCell *currentCell = (TestCell *)[tableView cellForRowAtIndexPath:indexPath];
// let's remove the activity indicator
[currentCell removeActivityIndicator];
// let's flag our model to indicate that this row is no longer loading
row.loading = NO;
});
}
And in this scenario, I need to make sure that my tableView:cellForRowAtIndexPath:
looks at the model data to figure out whether it needs to present the spinning activity indicator, too:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// if I'm using storyboards, the following isn't needed, but if not, I might use something
// like the following to load the custom cell from a NIB
//if (cell == nil)
//{
// NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TestCell" owner:self options:nil];
// cell = (TestCell *)[nib objectAtIndex:0];
//}
// this happens to be my model structure, where I have an array of sections,
// and each section has its array of Row objects for that section
Section *section = self.sections[indexPath.section];
Row *row = section.rows[indexPath.row];
// each "Row" object has two text fields, which I use to update the
// two labels in my TestCell subclass of UITableViewCell
cell.label1.text = row.text1;
cell.label2.text = row.text2;
// for this row of this section, figure out whether I need to start animating
// the UIActivityIndicator
if (row.loading)
[cell addActivityIndicator];
else
[cell removeActivityIndicator];
return cell;
}
And in my subclassed UITableViewCell
here is the code to add an activity indicator and to remove it:
@interface TestCell ()
@property (strong, nonatomic) UIActivityIndicatorView *activity;
@end
@implementation TestCell
- (void)addActivityIndicator
{
if (!self.activity)
{
self.activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.activity.center = self.contentView.center;
}
[self.contentView addSubview:self.activity];
[self.activity startAnimating];
}
- (void)removeActivityIndicator
{
if (self.activity)
{
[self.activity stopAnimating];
[self.activity removeFromSuperview];
self.activity = nil;
}
}
@end
This is all just a simple example of how it could work, but implementations may vary greatly (depending upon NIBs, storyboards, creating controls programmatically, the nature of your app's model, etc.). Rather than trying to retrofit the above code for your app, it will probably be easier for you to share your code with us and we'll hopefully be able to spot the problem pretty quickly. The problem is probably something simple.
Upvotes: 1