Well right now I am replacing my images from Instagram by getting to the bottom of the screen rather than adding new cells. How would I add new cells rather than replacing previous ones?
Here is my total implemantation file to retrieve the next page of images:
@interface StreamViewController () <UITextFieldDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) NSMutableDictionary *timelineResponse;
@property (nonatomic, strong) CredentialStore *credentialStore;
@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@end
@implementation StreamViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self refreshInstagram];
//Refresh
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(startRefresh:)
forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:refreshControl];
//Instigate Navigation Bar Buttons
UIButton *barButton = [UIButton buttonWithType:UIButtonTypeCustom];
[barButton setTitle:@"" forState:UIControlStateNormal];
[barButton setBackgroundImage:[UIImage imageNamed:@"barButton.png"] forState:UIControlStateNormal];
[barButton setBackgroundImage:[UIImage imageNamed:@"barButton_s.png"] forState:UIControlStateHighlighted];
[barButton addTarget:self action:@selector(didTapBarButton:) forControlEvents:UIControlEventTouchUpInside];
barButton.frame = CGRectMake(0.0f, 0.0f, 30.0f, 30.0f);
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:barButton];
self.navBar.leftBarButtonItem = barButtonItem;
UIButton *postButton = [UIButton buttonWithType:UIButtonTypeCustom];
[postButton setTitle:@"" forState:UIControlStateNormal];
[postButton setBackgroundImage:[UIImage imageNamed:@"pen_usIMG.png"] forState:UIControlStateNormal];
[postButton setBackgroundImage:[UIImage imageNamed:@"pen_sIMG.png"] forState:UIControlStateHighlighted];
[postButton addTarget:self action:@selector(didTapPostButton:) forControlEvents:UIControlEventTouchUpInside];
postButton.frame = CGRectMake(0.0f, 0.0f, 30.0f, 30.0f);
UIBarButtonItem *postButtonItem = [[UIBarButtonItem alloc] initWithCustomView:postButton];
self.navBar.rightBarButtonItem = postButtonItem;
//Reload by default
[self.collectionView reloadData];
}
//Global refresh Instagram Method
- (void)refreshInstagram {
[[InstagramClient sharedClient] getPath:@"users/self/feed"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Response: %@", responseObject);
self.timelineResponse = responseObject;
[self.collectionView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure: %@", error);
}];
}
- (void)nextInstagramPage:(NSIndexPath *)indexPath{
NSDictionary *page = self.timelineResponse[@"pagination"];
NSString *nextPage = page[@"next_url"];
[[InstagramClient sharedClient] getPath:[NSString stringWithFormat:@"%@",nextPage] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self.collectionView cellForItemAtIndexPath:indexPath];
self.timelineResponse = [responseObject mutableCopy];
[self.timelineResponse addEntriesFromDictionary:responseObject];
[self.collectionView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure: %@", error);
}];
}
- (NSMutableArray *)entries {
return self.timelineResponse[@"data"];
}
- (NSArray *)pages {
return self.timelineResponse[@"pagination"];
}
- (NSURL *)imageUrlForEntryAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *entry = [self entries][indexPath.row];
NSString *imageUrlString = entry[@"images"][@"standard_resolution"][@"url"];
return [NSURL URLWithString:imageUrlString];
}
#pragma mark - UICollectionViewDelegate
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
//int y = arc4random() % 200+50;
return CGSizeMake(150, 150);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
RNBlurModalView *modal = [[RNBlurModalView alloc] initWithViewController:self title:@"Item Tapped!" message:@"Thank God its working"];
[modal show];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y == roundf(scrollView.contentSize.height-scrollView.frame.size.height)) {
NSLog(@"we are at the endddd");
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.collectionView performBatchUpdates:^{
[self nextInstagramPage:indexPath];
} completion:^(BOOL finished) {
}
];
}
}
#pragma mark - UICollectionViewDataSource
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [[self entries] count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if ( indexPath.item == ([[self entries] count] - 1) ) {
// download more data and add it to the 'entries' array
[self refreshInstagram];
}
ImageCell *cell = (ImageCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"imageCell"
forIndexPath:indexPath];
NSURL *url = [self imageUrlForEntryAtIndexPath:indexPath];
NSLog(@"%@", url);
[cell.imageView setImageWithURL:url];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
#pragma mark - NavigationBarButtons
- (void)didTapBarButton:(id)sender {
[self.sidePanelController showLeftPanelAnimated:YES];
}
- (void)startRefresh:(UIRefreshControl *)sender {
[self refreshInstagram];
[sender endRefreshing];
}
-(void)didTapPostButton:(id)sender {
}
@end
Here is a way to add new cells:
-(void)addNewCells {
[self.collectionView performBatchUpdates:^{
int resultsSize = [[self entries]count];
[self.results addObjectsFromArray:newData];
NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
for (int i = resultsSize; i < resultsSize + newData.count; i++)
[arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
[self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
}
completion:nil];
}
You'll have to keep an array of the photos that are returned from the service. The dictionary won't work, as Mundi's answer suggests, because adding the responses from the dictionary is going to replace existing key/value pairs. That's why you're seeing the flashing.
Add an
NSMutableArray
property to your view controller and add entries from the data to it.And then user
self.photosArray
in yourentries
method.You simply increase your data array. Make
timelineResponse
into aNSMutableArray
and[self.timelineResponse addObjectsFromArray:responseObject];