Показывать пользовательскую метку, когда нет доступных данных для tableView - PullRequest
9 голосов
/ 30 января 2011

Данное приложение позволяет пользователям отмечать элементы как избранные.Когда у пользователя нет сохраненных избранных, я бы хотел уведомить их об этом (в основном я ненавижу идею пустого tableView).

Мой numberOfRowsInSection равен нулю, если нет элементов, отмеченных пользователем как избранные.Я хотел бы установить cell.textLabel.text = @ "У вас нет избранного", но когда нет элементов для таблицы, cellForRowAtIndexPath не вызывается.

Я могу проверить numberOfRowsInSection, чтобы получитьрезультат, когда он встречает 0 и затем проверяет 1 строку в cellForRowAtIndexPath, а затем вставляет пользовательский текст, но что тогда, если у них есть только один любимый текст?У меня было выше, и рекомендуется ниже, но, возможно, я не делаю это правильно, вероятно, из-за того, что это fetchedResultsController с методами делегата для обновления таблицы при изменении.

Я получаю эту ошибкукогда я удаляю ячейку, когда в таблице есть только одна ячейка:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1447.6.4/UITableView.m:976 Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted). with userInfo (null)

и когда ячеек нет для отображения в первую очередь, происходит сбой:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[_PFBatchFaultingArray objectAtIndex:]: index (0) beyond bounds (0)'

Вот соответствующий код:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];

    if ([sectionInfo numberOfObjects]==0) {
        return 1;
    } else {
        return [sectionInfo numberOfObjects];
    }
} 

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

if ([[_fetchedResultsController sections] objectAtIndex:0]==0) {
    cell.textLabel.text = @"You have no favorites";
} else {
    Shows *show = [_fetchedResultsController objectAtIndexPath:indexPath];

    cell.textLabel.text = show.ShowsToSerials.serialName;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", show.showTitle];
}
}

Ответы [ 3 ]

31 голосов
/ 30 января 2011

1) В моих собственных приложениях для iOS я создаю подпредставление с UILabel в нем, говоря «Нет результатов» Когда numberOfSectionsInTableView равно нулю, я добавляю подпредставление в табличное представление. Когда это! = Ноль, я удаляю это. Это, конечно, требует сохранения подпредставления в памяти как сохраненного объекта, чтобы вы могли удалить его.

2) Если вы хотите сделать одну ячейку, как вы уже упоминали: Когда numberOfSectionsInTableView равно нулю, вернуть 1. Затем в numberOfRowsInSection также вернуть 1. В cellForRowAtIndexPath проверьте оба параметра numberOfSectionsInTableView и numberOfRowsInSection, и, если они ДОЛЖНЫ быть равны нулю (после того, как вы вернули 1), отобразите любое сообщение.

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

Изменить, чтобы включить код: На самом деле это было немного иначе, чем я думал, но в основном то же самое. Здесь, очевидно, есть вещи, которые нужно изменить, чтобы они соответствовали вашему коду и вкусу.

(Обязательно укажите UIView * nomatchesView; в .h)

- (void)viewDidLoad{

        nomatchesView = [[UIView alloc] initWithFrame:self.view.frame];
        nomatchesView.backgroundColor = [UIColor clearColor];

        UILabel *matchesLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,320,320)];
        matchesLabel.font = [UIFont boldSystemFontOfSize:18];
        matchesLabel.minimumFontSize = 12.0f;
        matchesLabel.numberOfLines = 1;
        matchesLabel.lineBreakMode = UILineBreakModeWordWrap;
        matchesLabel.shadowColor = [UIColor lightTextColor];
        matchesLabel.textColor = [UIColor darkGrayColor];
        matchesLabel.shadowOffset = CGSizeMake(0, 1);
        matchesLabel.backgroundColor = [UIColor clearColor];
        matchesLabel.textAlignment =  UITextAlignmentCenter;

        //Here is the text for when there are no results
        matchesLabel.text = @"No Matches";


        nomatchesView.hidden = YES;
        [nomatchesView addSubview:matchesLabel];
        [self.tableView insertSubview:nomatchesView belowSubview:self.tableView];
    }



    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        //If there is no table data, unhide the "No matches" view
        if([data count] == 0 ){
        nomatchesView.hidden = NO;
        } else {
        nomatchesView.hidden = YES;
        }

        return [data count];
    }
9 голосов
/ 30 января 2011

Что бы я лично сделал, это следующее.Как вы сами сказали, в методе numberOfRowsInSection вы должны проверить счетчик вашего источника данных tableView, если его 0, то вы должны вернуть 1, чтобы отобразить нужную ячейку.

Затем в cellForRowAtIndexPath вы должны проверить счетчик.снова, если он возвращает 0, вы знаете, что табличное представление пытается нарисовать ваше «У вас нет избранных», и вы можете установить текст.

5 голосов
/ 03 марта 2015

Как упомянуто в приведенной ниже ссылке, легко, если мы создадим метку и установим ее в качестве фонового представления для UITableView, как показано ниже. http://www.appcoda.com/pull-to-refresh-uitableview-empty/

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    if (data) {

        self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
        return 1;

    } else {

        // Display a message when the table is empty
        UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];

        messageLabel.text = @"No data is currently available. Please pull down to refresh.";
        messageLabel.textColor = [UIColor blackColor];
        messageLabel.numberOfLines = 0;
        messageLabel.textAlignment = NSTextAlignmentCenter;
        messageLabel.font = [UIFont fontWithName:@"Palatino-Italic" size:20];
        [messageLabel sizeToFit];

        self.tableView.backgroundView = messageLabel;
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    }

    return 0;
}
...