UITableView загрузить больше при прокрутке вниз, как приложение Facebook

Я разрабатываю приложение, которое использует SQLite. Я хочу показать список пользователей (UITableView), используя механизм разбиения на страницы. Может ли кто-нибудь сказать мне, как загрузить больше данных в мой список, когда пользователь прокручивает до конца списка (например, на домашней странице в приложении Facebook)?

14 ответов


вы можете сделать это, добавив проверку того, где вы находитесь в cellForRowAtIndexPath: метод. Этот метод легко понять и реализовать :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Classic start method
    static NSString *cellIdentifier = @"MyCell";
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell)
    {
        cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MainMenuCellIdentifier];
    }

    MyData *data = [self.dataArray objectAtIndex:indexPath.row];
    // Do your cell customisation
    // cell.titleLabel.text = data.title;

    BOOL lastItemReached = [data isEqual:[[self.dataArray] lastObject]]; 
    if (!lastItemReached && indexPath.row == [self.dataArray count] - 1)
    {
        [self launchReload];
    }
}

EDIT: добавлена проверка последнего элемента для предотвращения вызовов рекурсии. Вам нужно будет реализовать метод, определяющий, достигнут ли последний элемент или нет.

EDIT2: объяснил lastItemReached


Свифт

метод 1: сделал прокрутку вниз

вот быстрая версия ответ Педру Романа. Когда пользователь прекращает прокрутку, он проверяет, достиг ли он дна.

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {

    // UITableView only moves in one direction, y axis
    let currentOffset = scrollView.contentOffset.y
    let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height

    // Change 10.0 to adjust the distance from bottom
    if maximumOffset - currentOffset <= 10.0 {
        self.loadMore()
    }
}

Метод 2: достигнута последняя строка

и вот быстрая версия ответ shinyuX. Он проверяет, достиг ли пользователь последней строки.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    // set up cell
    // ...

    // Check if the last row number is the same as the last current data element
    if indexPath.row == self.dataArray.count - 1 {
        self.loadMore()
    }

}

пример loadMore() метод

Я создал эти три переменные класса для извлечения пакетов данных.

// number of items to be fetched each time (i.e., database LIMIT)
let itemsPerBatch = 50

// Where to start fetching items (database OFFSET)
var offset = 0

// a flag for when all database items have already been loaded
var reachedEndOfItems = false

это функция для загрузки дополнительных элементов из базы данных в табличное представление.

func loadMore() {

    // don't bother doing another db query if already have everything
    guard !self.reachedEndOfItems else {
        return
    }

    // query the db on a background thread
    DispatchQueue.global(qos: .background).async {

        // determine the range of data items to fetch
        var thisBatchOfItems: [MyObjects]?
        let start = self.offset
        let end = self.offset + self.itemsPerBatch

        // query the database
        do {
            // SQLite.swift wrapper
            thisBatchOfItems = try MyDataHelper.findRange(start..<end)
        } catch _ {
            print("query failed")
        }

        // update UITableView with new batch of items on main thread after query finishes
        DispatchQueue.main.async {

            if let newItems = thisBatchOfItems {

                // append the new items to the data source for the table view
                self.myObjectArray.appendContentsOf(newItems)

                // reload the table view
                self.tableView.reloadData()

                // check if this was the last of the data
                if newItems.count < self.itemsPerBatch {
                    self.reachedEndOfItems = true
                    print("reached end of data. Batch count: \(newItems.count)")
                }

                // reset the offset for the next data query
                self.offset += self.itemsPerBatch
            }

        }
    }
}

лучше использовать willDisplayCell метод, чтобы проверить, будет ли загружена какая ячейка. Как только мы получим ток indexPath.row последнее, что мы можем загрузить больше ячеек. Это загрузит больше ячеек при прокрутке вниз.

 - (void)tableView:(UITableView *)tableView 
       willDisplayCell:(UITableViewCell *)cell    
       forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // check if indexPath.row is last row
    // Perform operation to load new Cell's.
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    NSInteger lastSectionIndex = [tableView numberOfSections] - 1;
    NSInteger lastRowIndex = [tableView numberOfRowsInSection:lastSectionIndex] - 1;
    if ((indexPath.section == lastSectionIndex) && (indexPath.row == lastRowIndex)) {
        // This is the last cell
        [self loadMore];
    }
}

если вы используете основные данные и NSFetchedResultsController, потом loadMore может выглядеть следующим образом:

// Load more
- (void)loadMore {
    [self.fetchedResultsController.fetchRequest setFetchLimit:newFetchLimit];
    [NSFetchedResultsController deleteCacheWithName:@"cache name"];
    NSError *error;
    if (![self.fetchedResultsController performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }

    [self.tableView reloadData];
}

я реализовал одно решение, которое я нашел в stackoverflow, и оно отлично работает, но я думаю, что решение shinyuX очень легко реализовать и отлично работает для моего предложения. Если кто-то хочет другое решение, можете использовать это ниже.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

   // UITableView only moves in one direction, y axis
    CGFloat currentOffset = scrollView.contentOffset.y;
    CGFloat maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;

    //NSInteger result = maximumOffset - currentOffset;

    // Change 10.0 to adjust the distance from bottom
    if (maximumOffset - currentOffset <= 10.0) {
        [self loadOneMorePage];
        //[self methodThatAddsDataAndReloadsTableView];
    }
}

подробности

xCode 8.3.1, Swift 3.1

решение

import UIKit

class LoadMoreActivityIndicator {

    let spacingFromLastCell: CGFloat
    let spacingFromLastCellWhenLoadMoreActionStart: CGFloat
    let activityIndicatorView: UIActivityIndicatorView
    weak var tableView: UITableView!

    private var defaultY: CGFloat {
        return tableView.contentSize.height + spacingFromLastCell
    }

    init (tableView: UITableView, spacingFromLastCell: CGFloat, spacingFromLastCellWhenLoadMoreActionStart: CGFloat) {
        self.tableView = tableView
        self.spacingFromLastCell = spacingFromLastCell
        self.spacingFromLastCellWhenLoadMoreActionStart = spacingFromLastCellWhenLoadMoreActionStart
        let size:CGFloat = 40
        let frame = CGRect(x: (tableView.frame.width-size)/2, y: tableView.contentSize.height + spacingFromLastCell, width: size, height: size)
        activityIndicatorView = UIActivityIndicatorView(frame: frame)
        activityIndicatorView.color = .black
        activityIndicatorView.isHidden = false
        activityIndicatorView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin]
        tableView.addSubview(activityIndicatorView)
        activityIndicatorView.isHidden = isHidden
    }

    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private var isHidden: Bool {
        if tableView.contentSize.height < tableView.frame.size.height {
            return true
        } else {
            return false
        }
    }

    func scrollViewDidScroll(scrollView: UIScrollView, loadMoreAction: ()->()) {
        let offsetY = scrollView.contentOffset.y
        activityIndicatorView.isHidden = isHidden
        if !isHidden && offsetY >= 0 {
            let contentDelta = scrollView.contentSize.height - scrollView.frame.size.height
            let offsetDelta = offsetY - contentDelta

            let newY = defaultY-offsetDelta
            if newY < tableView.frame.height {
                activityIndicatorView.frame.origin.y = newY
            } else {
                if activityIndicatorView.frame.origin.y != defaultY {
                    activityIndicatorView.frame.origin.y = defaultY
                }
            }

            if !activityIndicatorView.isAnimating {
                if offsetY > contentDelta && offsetDelta >= spacingFromLastCellWhenLoadMoreActionStart && !activityIndicatorView.isAnimating {
                    activityIndicatorView.startAnimating()
                    loadMoreAction()
                }
            }

            if scrollView.isDecelerating {
                if activityIndicatorView.isAnimating && scrollView.contentInset.bottom == 0 {
                    UIView.animate(withDuration: 0.3) { [weak self] in
                        if let bottom = self?.spacingFromLastCellWhenLoadMoreActionStart {
                            scrollView.contentInset = UIEdgeInsetsMake(0, 0, bottom, 0)
                        }
                    }
                }
            }
        }
    }

    func loadMoreActionFinshed(scrollView: UIScrollView) {

        let contentDelta = scrollView.contentSize.height - scrollView.frame.size.height
        let offsetDelta = scrollView.contentOffset.y - contentDelta
        if offsetDelta >= 0 {
            // Animate hiding when activity indicator displaying
            UIView.animate(withDuration: 0.3) {
                scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
            }
        } else {
            // Hiding without animation when activity indicator displaying
            scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
        }

        activityIndicatorView.stopAnimating()
        activityIndicatorView.isHidden = false
    }
}

использование

extension ViewController: UITableViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        activityIndicator.scrollViewDidScroll(scrollView: scrollView) {
            DispatchQueue.global(qos: .utility).async {
                for i in 0..<3 {
                    print(i)
                    sleep(1)
                }
                DispatchQueue.main.async { [weak self] in
                    self?.activityIndicator.loadMoreActionFinshed(scrollView: scrollView)
                }
            }
        }
    }
}

Полная Выборка

ViewController.Свифт!--7-->

import UIKit

class ViewController: UIViewController {

    var count = 30

    @IBOutlet weak var tableView: UITableView!
    fileprivate var activityIndicator: LoadMoreActivityIndicator!
    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource = self
        tableView.delegate = self
        tableView.tableFooterView = UIView()
        activityIndicator = LoadMoreActivityIndicator(tableView: tableView, spacingFromLastCell: 10, spacingFromLastCellWhenLoadMoreActionStart: 60)
        print(tableView.frame)
    }
}

extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = "\(indexPath)"
        return cell
    }
}

extension ViewController: UITableViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        activityIndicator.scrollViewDidScroll(scrollView: scrollView) {
            DispatchQueue.global(qos: .utility).async {
                for i in 0..<3 {
                    print("!!!!!!!!! \(i)")
                    sleep(1)
                }
                DispatchQueue.main.async { [weak self] in
                    self?.activityIndicator.loadMoreActionFinshed(scrollView: scrollView)
                }
            }
        }
    }
}

Main.раскадровка

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_20269474" customModuleProvider="target" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="6la-L6-Fo3">
                                <rect key="frame" x="0.0" y="20" width="375" height="647"/>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                            </tableView>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="6la-L6-Fo3" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="GvO-lp-VW8"/>
                            <constraint firstAttribute="trailing" secondItem="6la-L6-Fo3" secondAttribute="trailing" id="aGF-Ie-T6Y"/>
                            <constraint firstItem="6la-L6-Fo3" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="obO-Sn-WYo"/>
                            <constraint firstItem="6la-L6-Fo3" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="zp5-B1-sWe"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="tableView" destination="6la-L6-Fo3" id="4lR-IX-vtT"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="48.799999999999997" y="37.331334332833585"/>
        </scene>
    </scenes>
</document>

enter image description here

результат

enter image description here


используйте limit и offset в своих запросах и заполните свой tableview этим контентом. Когда пользователь прокручивает вниз, загрузите следующее смещение.

реализовать tableView:willDisplayCell:forRowAtIndexPath: метод UITableViewDelegate и проверьте, не последняя ли это строка


Ниже ссылка предоставит пример кода. #Swift3

пользователь должен вытащить последнюю ячейку представления таблицы, по крайней мере, высоту ячейки 2, чтобы получить больше данных с сервера.

вы найдете ячейку процесса также, чтобы показать процесс загрузки, как в последней ячейке.

его в Swift3

https://github.com/yogendrabagoriya/YBTableViewPullData


еще один вариант использования ( Swift 3 и iOS 10+):

class DocumentEventsTableViewController: UITableViewController, UITableViewDataSourcePrefetching {

     var currentPage: Int = 1

     override func viewDidLoad() {
         super.viewDidLoad()

         self.tableView.prefetchDataSource = self
     }

     func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
         let upcomingRows = indexPaths.map { .row }

         if let maxIndex = upcomingRows.max() {

            let nextPage: Int = Int(ceil(Double(maxIndex) / Double(APICall.defaultPageSize))) + 1

            if nextPage > currentPage {
                 // Your function, which attempts to load respective page from the local database
                 loadLocalData(page: nextPage)

                 // Your function, which makes a network request to fetch the respective page of data from the network
                 startLoadingDataFromNetwork(page: nextPage) 

                 currentPage = nextPage
             }
         }
     }
 }

для небольших страниц (~ 10 элементов) вы можете вручную добавить данные для страниц 1 и 2, потому что nextPage может быть где-то около 1-2, пока в таблице не будет несколько элементов для прокрутки. Но он будет отлично работать для всех следующих страниц.


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

    if (news.count == 0) {
        return 0;
    } else {
        return news.count +  1 ;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    @try {

        uint position = (uint) (indexPath.row);
        NSUInteger row = [indexPath row];
        NSUInteger count = [news count];

        //show Load More
        if (row == count) {
            UITableViewCell *cell = nil;

            static NSString *LoadMoreId = @"LoadMore";
            cell = [tableView dequeueReusableCellWithIdentifier:LoadMoreId];
            if (cell == nil) {
                cell = [[UITableViewCell alloc]
                        initWithStyle:UITableViewCellStyleDefault
                      reuseIdentifier:LoadMoreId];
            }
            if (!hasMoreLoad) {
                cell.hidden = true;
            } else {

                cell.textLabel.text = @"Load more items...";
                cell.textLabel.textColor = [UIColor blueColor];
                cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
                NSLog(@"Load more");
                if (!isMoreLoaded) {
                    isMoreLoaded = true;
                    [self performSelector:@selector(loadMoreNews) withObject:nil afterDelay:0.1];
                }
            }

            return cell;

        } else {
            NewsRow *cell = nil;

            NewsObject *newsObject = news[position];
            static NSString *CellIdentifier = @"NewsRow";
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

            if (cell == nil) {
                // Load the top-level objects from the custom cell XIB.
                NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
                // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
                cell = topLevelObjects[0];
                // Configure the cell...

            }

            cell.title.text = newsObject.title;             
            return cell;
        }

    }
    @catch (NSException *exception) {
        NSLog(@"Exception occurred: %@, %@", exception, [exception userInfo]);
    }
    return nil;
}

очень хорошее объяснение на этот пост.

http://useyourloaf.com/blog/2010/10/02/dynamically-loading-new-rows-into-a-table.html

просто вы должны добавить последнюю строку и скрыть ее, и когда строка таблицы попала в последнюю строку, чем показать строку и загрузить больше элементов.


просто хочу поделиться такой подход:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    NSLog(@"%@", [[YourTableView indexPathsForVisibleRows] lastObject]);
    [self estimatedTotalData];
}

- (void)estimatedTotalData
{
    long currentRow = ((NSIndexPath *)[[YourTableView indexPathsForVisibleRows] lastObject]).row;

    long estimateDataCount = 25;

    while (currentRow > estimateDataCount)
    {
        estimateDataCount+=25;
    }

    dataLimit = estimateDataCount;

    if (dataLimit == currentRow+1)
    {
        dataLimit+=25;
    }

    NSLog(@"dataLimit :%ld", dataLimit);

    [self requestForData];

    // this answers the question..
    //
    if(YourDataSource.count-1 == currentRow)
    {
        NSLog(@"LAST ROW"); //loadMore data
    }
}

NSLog(...); вывод будет примерно таким:

<NSIndexPath: 0xc0000000002e0016> {length = 2, path = 0 - 92}
dataLimit :100
<NSIndexPath: 0xc000000000298016> {length = 2, path = 0 - 83}
dataLimit :100
<NSIndexPath: 0xc000000000278016> {length = 2, path = 0 - 79}
dataLimit :100
<NSIndexPath: 0xc000000000238016> {length = 2, path = 0 - 71}
dataLimit :75
<NSIndexPath: 0xc0000000001d8016> {length = 2, path = 0 - 59}
dataLimit :75
<NSIndexPath: 0xc0000000001c0016> {length = 2, path = 0 - 56}
dataLimit :75
<NSIndexPath: 0xc000000000138016> {length = 2, path = 0 - 39}
dataLimit :50
<NSIndexPath: 0xc000000000120016> {length = 2, path = 0 - 36}
dataLimit :50
<NSIndexPath: 0xc000000000008016> {length = 2, path = 0 - 1}
dataLimit :25
<NSIndexPath: 0xc000000000008016> {length = 2, path = 0 - 1}
dataLimit :25

это хорошо для отображения данных, хранящихся локально. Первоначально я объявляю dataLimit 25, что означает, что uitableview будет иметь 0-24 (изначально).

если пользователь прокрутил вниз и последняя ячейка видна dataLimit будет добавлена 25...

Примечание: это больше похоже на подкачку данных UITableView,:)


-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

NSInteger sectionsAmount = [tableView numberOfSections];
NSInteger rowsAmount = [tableView numberOfRowsInSection:[indexPath section]];
if ([indexPath section] == sectionsAmount - 1 && [indexPath row] == rowsAmount - 1) {
    //get last row
    if (!isSearchActive && !isFilterSearchActive) {
        if (totalRecords % 8 == 0) {
            int64_t delayInSeconds = 2.0;
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {


            [yourTableView beginUpdates];
            [yourTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
            [yourTableView endUpdates];
            });
        }
    }
}
}

лучший способ решить эту проблему-добавить ячейки в нижней части таблицы, и эта ячейка будет содержать индикатор.

в swift вам нужно добавить следующее:

  1. создать новую ячейку типа cellLoading это будет содержать индикатор. Посмотрите на код ниже
  2. посмотрите на число строк и добавьте к нему 1 (это для ячейки загрузки).
  3. вам нужно проверить в rawAtIndex, если idexPath.row == yourArray.count затем возвращает ячейку загрузки.

посмотрите на код ниже:

import UIKit

class LoadingCell: UITableViewCell {

@IBOutlet weak var indicator: UIActivityIndicatorView!


}

для представления таблицы : numOfRows:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return  yourArray.count + 1
}

cellForRawAt indexPath:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if indexPath.row == users.count  {
        // need to change
        let loading = Bundle.main.loadNibNamed("LoadingCell", owner: LoadingCell.self , options: nil)?.first as! LoadingCell
        return loading

    }

    let yourCell = tableView.dequeueReusableCell(withIdentifier: "cellCustomizing", for: indexPath) as! UITableViewCell

    return yourCell

}

Если вы заметили, что моя ячейка загрузки создана из файла nib. это видео объясню, что я сделал.


let threshold = 100.0 // threshold from bottom of tableView
var isLoadingMore = false // flag


func scrollViewDidScroll(scrollView: UIScrollView) {
    let contentOffset = scrollView.contentOffset.y
    let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;

    if !isLoadingMore && (maximumOffset - contentOffset <= threshold) {
        // Get more data - API call
        self.isLoadingMore = true

        // Update UI
        dispatch_async(dispatch_get_main_queue()) {
            tableView.reloadData()
            self.isLoadingMore = false
        }
    }
  }