How to implement endless loading in table or colle

2019-02-15 18:50发布

问题:

I’m building an article reading app. I’m fetching data from JSON link like article image and title in uitableview.

I’m unable to implement pagination in uitableview, let say my JSON link is www.example.com&page=1 contain 10 articles at a time which is 1-10.

When I concatenate in the JSON link like www.example.com&page=2 to get 11-20 article list.

I’m unable to implement how I can load the data in uitableview on scrolling and increase no.of rows with data.

Here is my code:

     int *x=1;
    int *inc=10;

    @interface ysTableViewController ()

    {
     Reachability *internetReachable;
     }
     @end

      @implementation ysTableViewController

    - (id)initWithStyle:(UITableViewStyle)style
  {
         self = [super initWithStyle:style];
        if (self) {
    // Custom initialization
        }
      return self;
   }

    - (void)viewDidLoad
    {
       [super viewDidLoad];
        [self checkInternetConnection];
       UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20,10,0,20)];
       titleLabel.textColor = [UIColor blackColor];
       titleLabel.backgroundColor = [UIColor clearColor];
       titleLabel.text = @"Story";
     [self.navigationItem setTitleView:titleLabel];


         }

  - (void)scrollViewDidScroll:(UIScrollView *)aScrollView {

    CGPoint offset = aScrollView.contentOffset;

   CGRect bounds = aScrollView.bounds;

   CGSize size = aScrollView.contentSize;

    UIEdgeInsets inset = aScrollView.contentInset;

    float y = offset.y + bounds.size.height - inset.bottom;

   float h = size.height;

    float reload_distance = 10;

     if(y > h + reload_distance) {

      NSLog(@"load more rows");

       inc=inc+10;

      BOOL myBool = [self isNetworkAvailable];

       if (myBool)

    {

        @try {

            // for table cell seperator line color

            self.tableView.separatorColor = [UIColor colorWithRed:190/255.0 green:190/255.0 blue:190/255.0 alpha:1.0];

            // for displaying the previous screen lable with back button in details view controller

            UIBarButtonItem *backbutton1 = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];

           [[self navigationItem] setBackBarButtonItem:backbutton1];

             _Title1 = [[NSMutableArray alloc] init];

            _Author1 = [[NSMutableArray alloc] init];

            _Images1 = [[NSMutableArray alloc] init];

            _Details1 = [[NSMutableArray alloc] init];

            _link1 = [[NSMutableArray alloc] init];

            _Date1 = [[NSMutableArray alloc] init];

             NSString *urlString=[NSString stringWithFormat:@“www.example.com&page=%d",x];

            NSLog(@"xxxxx===%d",x);

           NSURL *newUrl=[NSURL URLWithString:urlString];

             NSData* data = [NSData dataWithContentsOfURL:newUrl];

            NSArray *ys_avatars = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

             x++;

          if(ys_avatars){

            for (int j=0;j<ys_avatars.count;j++)

                {

                    [_Title1 addObject:ys_avatars[j][@"title"]];

                    [_Author1 addObject: ys_avatars[j][@"author"]];

                    [_Images1 addObject: ys_avatars[j][@"featured_img"]];

                    [_Details1 addObject:ys_avatars[j][@"content"]];

                    [_link1 addObject:ys_avatars[j][@"permalink"]];

                    NSString *newStr=[ys_avatars[j][@"date"] substringToIndex:[ys_avatars[j][@"date"] length]-3];

                    [_Date1 addObject:newStr];

                }        }

            else

            {

                NSLog(@"asd");

                  }    }

           @catch (NSException *exception) {

           }        

         }

      }

   }

       - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

      {

// Return the number of sections.

      return 1;

     }

      - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    {

// Return the number of rows in the section.

      return inc;

         }

          - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

       {

       static NSString *Cellidentifier1 = @"ysTableViewCell";

         ysTableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];

          // Configure the cell...

        long row = [indexPath row];

         cell1.TitleLabel1.text = _Title1[row];

         cell1.AuthorLabel1.text = _Author1[row];

             NSString *yourStoryUrl = [_Images1[indexPath.row] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

      if(yourStoryUrl) {

            NSArray *subStringsUrl = [yourStoryUrl componentsSeparatedByString:@"/"];

         NSString *stripedName = [subStringsUrl lastObject];

         NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString *documentsDirectory = [paths objectAtIndex:0];

    //Local stored image file path

           NSString* filePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",stripedName]];

           if(filePath) {

            UIImage *image = [UIImage imageWithContentsOfFile:filePath];

             if(image) {

            // Now the image will have been loaded and decoded and is ready to rock for the main thread

                ysTableViewCell  *updateCell =(id)[tableView cellForRowAtIndexPath:indexPath];

                if(updateCell)

                    updateCell.ThumbImage1.image=image;

                cell1.ThumbImage1.image=image;

          } else {

            dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

            dispatch_async(taskQ, ^{

                NSURL *Imageurl = [NSURL URLWithString:yourStoryUrl];

                NSData *data =  [NSData dataWithContentsOfURL:Imageurl];

                UIImage *images1 = [[UIImage alloc] initWithData:data];

              NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

                NSString *documentsDirectory = [paths objectAtIndex:0];

                NSData *imageData = UIImagePNGRepresentation(images1);

                //_imagePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png",stripedName]];



                // NSLog((@"pre writing to file"));

                if (![imageData writeToFile:filePath atomically:NO])

                {

                    NSLog((@"Failed to cache image data to disk"));

                }

                else

                {

                    NSLog((@"the cachedImagedPath is %@",filePath));

                }

                // Now the image will have been loaded and decoded and is ready to rock for the main thread

                dispatch_sync(dispatch_get_main_queue(), ^{

                    ysTableViewCell  *updateCell =(id)[tableView cellForRowAtIndexPath:indexPath];

                    if(updateCell)

                        updateCell.ThumbImage1.image=images1;

                    cell1.ThumbImage1.image=images1;

                });

                  });

        }



    } else {

        dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        dispatch_async(taskQ, ^{

            NSURL *Imageurl = [NSURL URLWithString:yourStoryUrl];

            NSData *data =  [NSData dataWithContentsOfURL:Imageurl];

            UIImage *images1 = [[UIImage alloc] initWithData:data];

            //        NSString *myString = [Imageurl absoluteString];

            //        NSLog(@"%@",myString);

            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

            NSString *documentsDirectory = [paths objectAtIndex:0];



             NSData *imageData = UIImagePNGRepresentation(images1);

             _imagePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png",stripedName]];



            // NSLog((@"pre writing to file"));

            if (![imageData writeToFile:_imagePath atomically:NO])

            {

                NSLog((@"Failed to cache image data to disk"));

            }

            else

            {

              //  NSLog((@"the cachedImagedPath is %@",_imagePath));

            }

         // Now the image will have been loaded and decoded and is ready to rock for the main thread

              dispatch_sync(dispatch_get_main_queue(), ^{

                 ysTableViewCell  *updateCell =(id)[tableView           cellForRowAtIndexPath:indexPath];

                if(updateCell)

                    updateCell.ThumbImage1.image=images1;

                cell1.ThumbImage1.image=images1;

            });

           });

    }

}

return cell1;

  }

回答1:

This is by no means easy. IN GENERAL TERMS you need code that looks like this..

Note the four very distinct parts of this fundamental routine.

I have never found a working "general" package solution for this problem.

Again, look to the "four sections" in this: they give the logic you're looking for!

-(void)forTerm:(NSString *)term doPageAfter:(int)doingThisPage
  {

  doingThisPage = doingThisPage + 1;
  if ( doingThisPage > 20 ) return; // never, ever, ever forget that!! heh.

  [CLOUD search:term page:doingThisPage then:^(NSArray *thoseTenResults)
    {




    self.searchSpinner.hidden = YES;

    // (step 1) IF IT IS "PAGE 1", we need to re-kick-off the array...
    if ( doingThisPage == 1 )
      CLOUD.searchResultsRA = [[NSMutableArray alloc] init];




    // (step 2) go ahead and add on these results

    if ( doingThisPage == 1 )
      {
      [CLOUD.searchResultsRA addObjectsFromArray:thoseTenResults];
      [self.searchDisplay safelyReloadBouncyTable];
      }
    else
      {
      [self.searchDisplay.collectionView performBatchUpdates:^
        {
        NSUInteger oldSize = CLOUD.searchResultsRA.count;
        [CLOUD.searchResultsRA addObjectsFromArray:thoseTenResults];
        NSUInteger newSize = CLOUD.searchResultsRA.count;

        NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
        for (NSUInteger i = oldSize; i < newSize; i++)
          [arrayWithIndexPaths
              addObject:[NSIndexPath indexPathForRow:i inSection:0]];

        [self.searchDisplay justSignal];
        [self.searchDisplay.collectionView
           insertItemsAtIndexPaths:arrayWithIndexPaths];
        }
        completion:nil];
      }




    // (step 3) indeed if it's the first page, do a drop-in for fun
    if ( doingThisPage == 1 ) [self.searchDisplay.view dropIn:nil];
    // (for a "new search" which is now being displayed, in your UX
    // there would be some sort of indication of that fact - do it here)




    // (step 4) IF there WERE results .. try another page!
    if ( thoseTenResults.count > 0 )
      [self forTerm:term doPageAfter:doingThisPage];
      // note we are calling this same routine, again!!!
    }
    ];
  }