Add more cells UICollectionView

2019-05-07 06:20发布

问题:

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];
}

回答1:

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.

[self.photosArray addObjectsFromArray:responseObject[@"data"]];

And then user self.photosArray in your entries method.



回答2:

You simply increase your data array. Make timelineResponse into a NSMutableArray and

[self.timelineResponse addObjectsFromArray:responseObject];

[self.timelineResponse addEntriesFromDictionary:responseObject];
[self.collectionView reloadData];