Reputation: 1404
I have an array of products meant to be displayed in a tableView (dynamic cells) :
{"Products" :
[
{
"NAME": "MyProduct1",
"TIMELINE": 4
},
{
"NAME": "MyProduct2",
"TIMELINE": 10
},
{
"NAME": "MyProduct3",
"TIMELINE": 18
},
...
]}
The TIMELINE property is supposed to define the number of seconds after which the cell is displayed.
The starting point for the timeline is defined elsewhere and not always equal to 0. It can be for example 12, in this case :
My cells are filled with :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyResults* media = [MyResults getInstance];
[media productDetails:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"results" forIndexPath:indexPath];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:666];
nameLabel.text = media.productName;
cell.clipsToBounds = YES;
return cell;
}
MyResults.m :
_products = [json objectForKey:@"Products"];
-(void)productDetails:(NSUInteger)row {
NSDictionary* details = [_products objectAtIndex:row];
_productName= [details objectForKey:@"NAME"];
}
From my research I have found two approaches, but can't get them to work :
Method 1 : insertrowsatindexpaths
I would like to filter the main array so it only keeps TIMELINE > STARTINGPOINT products.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(%@ > %@)", timelineValue, startingPoint];
I'm having a hard time retrieving timelineValue, since my products array is parsed with cellForRowAtIndexPath in the first place.
Method 2 : heightforrowatindexpath
The array is fully loaded in tableView, height is set to 0 and set back to normal when the TIMELINE time is reached. I can set it to 0 but can't figure how to set a NSTimer to give it original height.
I'm not sure if any of this is a good solution, especially with memory management matters. Any thoughts appreciated.
Bonus : the cell display have to be animated
Upvotes: 1
Views: 339
Reputation: 2168
Assuming you have a view controller with an UITableView, you'll also need to retain a local timeStart variable and two arrays - one for the products, and one for the products which we already added to the table view:
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) NSArray *products;
@property (nonatomic, strong) NSMutableArray *dataSource;
@property (nonatomic) NSInteger timelineStart;
@end
Your viewDidLoad should look like that:
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = [NSMutableArray array];
self.timelineStart = 0; // TODO: CHANGE IT TO WHAT YOU NEED
self.products = [NSArray arrayWithObjects:@{@"NAME" : @"MyProduct1", @"TIMELINE" : @(4)}, @{@"NAME" : @"MyProduct2", @"TIMELINE" : @(10)}, @{@"NAME" : @"MyProduct3", @"TIMELINE" : @(18)},nil];
// Change the products parsing to whatever you need
for (NSInteger i = 0; i < self.products.count; i++) {
NSDictionary *obj = [self.products objectAtIndex:i];
if ([[obj objectForKey:@"TIMELINE"] integerValue] > self.timelineStart) {
NSInteger timeInterval = [[obj objectForKey:@"TIMELINE"] integerValue] - self.timelineStart;
[NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(addNewProductToTableView:) userInfo:obj repeats:NO];
}
}
}
- (void)addNewProductToTableView:(NSTimer *)timer
{
NSDictionary *obj = [timer userInfo];
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *indexPaths = [NSMutableArray array];
NSInteger currentCount = self.dataSource.count;
[indexPaths addObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[self.dataSource insertObject:obj atIndex:0];
// tell the table view to update (at all of the inserted index paths)
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
});
}
And finally the must have tableview delegate.
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataSource count];
}
#pragma mark - UITableViewDelegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyIdentifier"];
}
NSDictionary *item = [self.dataSource objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:@"NAME"];
return cell;
}
Hope this answer your demands (it also includes the animation).
Upvotes: 2