Подтвердить что ты не робот

Как удалить статическую ячейку из UITableView, разработанного в StoryBoard

Решение, вероятно, очень простое, но я не мог просто найти его.!

Работа с раскадрой (iOS 5), у меня есть tableViewController и разработанный STATIC tableview с 5 разделами, с разными статическими ячейками внутри каждого раздела.

Мой вопрос: как программно удалить ячейку в viewWillAppear?

Например, у меня есть ячейка, предназначенная для даты

IBOutlet UITableViewCell * cellForDate;

И.. если нет даты, я хочу удалить свою ячейку.

cellForDate.hidden = true; //Hide the cell, but leave a blank space

Ive try [tableView deleteRowsAtIndexPaths...] не работает

У кого-нибудь появилась идея?

4b9b3361

Ответ 1

Попробуйте скрыть ячейку до ее отображения в методе UITableViewDelegate tableView:willDisplayCell:forRowAtIndexPath:. Это окончательный метод, где вы можете манипулировать внешним видом ячейки. Это, однако, не удалит пространство, которое должна принять ячейка, поэтому еще одна вещь, которую вы можете попробовать, - установить высоту строки ячейки до 0, используя метод tableView:heightForRowAtIndexPath: того же протокол.

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

Ответ 2

Надеюсь, это немного больше универсального решения, но оно все еще не идеально.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    if (cell.hidden) {
        return 0;
    } else {
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
}

С помощью этого метода вы установите скрытую связанную ячейку IBOutlet, а затем, когда таблица попытается отобразить строку, она сначала проверяет, должна ли ячейка (с помощью супервызов получить ячейку) скрываться, если это так он возвращает высоту 0, которая эффективно удаляет ее из списка. Если ячейку не следует скрывать, она получает высоту от супер, поэтому все, что обычно происходит, все равно происходит.

Единственная проблема заключается в том, что начальная и конечная ячейки отвечают за разделитель в верхней и нижней частях списка или группы. Поэтому, если вы спрячете последнюю ячейку в группе, нижний делитель в группе будет вставляться немного, как на обычных строках, а не на полную ширину. Это только проблема, если вы скрываете верхние или нижние строки. И вы используете разделитель. И вы заботитесь о полностью стандартном отображении. Лучшим решением в моем случае было просто не скрывать верхние или нижние строки. Я переместил любой контент, который может быть скрыт до середины группы. В качестве альтернативы вы можете просто согласиться с тем, что он не является стандартным или отключает разделители строк в вашей таблице.

Ответ 3

Если вы хотите окончательно удалить ячейку tableview, просто вызовите deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone] с помощью indexPath, соответствующего вашей строке. Вам также потребуется уменьшить число строк, возвращаемых numberOfRowsInSection:.

Тем не менее, я искал способ временно "удалить" нежелательные статические ячейки tableview из статического табличного представления, потому что я хотел, чтобы определенная строка была там иногда, а иногда и нет. Я также хотел иметь возможность обновлять это по требованию из-за пределов контроллера таблицы.

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

Во-первых, я создал публичный метод в контроллере tableview для обновления переменных состояния и запуска повторного отображения:

- (void)updateSettingsDisplay:(BOOL)hideSetting
{
    if (hideSetting == self.hideSetting) {
        return; // no need to do anything because it didn't change
    }

    self.hideSetting = hideSetting;
    self.numRows = (hideSetting)? kNumRowsWithSetting : kNumRowsWithoutSetting;

    // redisplay only if we're visible
    if (!self.viewJustLoaded && (self.navController.visibleViewController == self)) {
        [self.tableView reloadData];
    }
    self.viewJustLoaded = NO;
}

Контроллер tableview viewDidLoad выглядит следующим образом:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // check whether or not to display out-of-coverage tableview cell
    self.hideSetting = YES; // initial value; could just as easily be NO
    self.viewJustLoaded = YES;
    [self updateSettingsDisplay];
}

делегат данных-источника данных:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return self.numRows;
}

и, наконец,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // set row to the index of the stored tableView cell that corresponds to the
    // cell you want (its location in the static tableview from your storyboard)
    NSInteger row = indexPath.row;
    if (self.hideSetting) {
        // skip drawing setting tableviewcell (since the setting we're hiding is
        // first, we can just increment the row to get the one we want)
        ++row;
        assert(row < kTotalRows); // bounds checking just to convince yourself (remove after testing)
    }
    // get a new index path since the row field is read-only
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];

    // grab the cell from super that corresponds to the cell you want
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:newIndexPath]; // static table

    return cell;
}

Фокус в том, что статические ячейки всегда доступны в [super tableView:tableView cellForRowAtIndexPath:newIndexPath] - поэтому используйте это для постоянного хранения ваших статических ячеек таблицы. Затем отрегулируйте количество строк по мере необходимости и правильно сопоставьте строки (т.е. Получите строку сохраненной ячейки, которая соответствует ячейке, которую вы хотите отобразить) в своем делегате tableview cellForRowAtIndexPath:.

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

Ответ 4

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    if(indexPath.section == 1) { //For example
        return 0
    }
}

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if(indexPath.section == 1) {
         cell.hidden = true
    }
}

Ответ 5

Swift 3

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if indexPath.section == 0 {
        cell.isHidden = true
    }
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == 0 {
        return 0
    } else {
        return super.tableView(tableView, heightForRowAt: indexPath)
    }
}

Ответ 6

Вам нужно поставить beginUpdates перед вызовом delete и endUpdates после:

[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:r inSection:s]]];
[tableView endUpdates];

В ответ на ваш комментарий:

- (NSInteger)tableView:(UITableView)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger ret;
    switch (section) {
        case 0:
            // sectionZeroRows doesnt have to be a 
            // property (an attribute works just fine), but it
            // helps with explaining this example.
            ret = self.sectionZeroRows;
            break;
        // ...
    }
    return ret;
}

- (void)someMethod {
    --self.sectionZeroRows;
    [tableView beginUpdates];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]]];
    [tableView endUpdates];
}

Ответ 7

вы можете посмотреть на это

https://github.com/xelvenone/StaticDataTableViewController/

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

self.hideSectionsWithHiddenRows = YES; //YES, NO
[self cell:self.outletToMyStaticCell1 setHidden:hide];
[self cell:self.outletToMyStaticCell2 setHidden:hide];
[self reloadDataAnimated:YES];

Ответ 8

FYI (прокомментировал бы, если бы мог), если вы переопределяете статический UITableView Grouped из раскадровки, тогда вам также необходимо переопределить виды и высоты верхнего и нижнего колонтитулов для каждого раздела, который вы изменяете/скрываете.

Мне также нужно было установить возвращаемое значение для методов "GetHeight" для чего-то другого, кроме нуля, - подразумевая, что нулевое значение означает что-то еще (автоопределение, "не установлено" или тому подобное).

Ниже приведен код в Xamarin iOS С#, но он переводится непосредственно в соответствующие методы Obj-C:

    public override void WillDisplayHeaderView(UITableView tableView, UIView headerView, nint section)
    {
        if (section == 0)
        {
            headerView = new UIView(new CGRect(0,0,0,0));
        }
    }

    public override nfloat GetHeightForHeader(UITableView tableView, nint section)
    {
        if (section == 0)
        {
            return 1f;
        }
        return base.GetHeightForHeader(tableView, section);
    }

    public override void WillDisplayFooterView(UITableView tableView, UIView footerView, nint section)
    {
        if (section == 0)
        {
            footerView = new UIView(new CGRect(0, 0, 0, 0));
        }
    }

    public override nfloat GetHeightForFooter(UITableView tableView, nint section)
    {
        if (section == 0)
        {
            return 1f;
        }
        return base.GetHeightForFooter(tableView, section);
    }

Ответ 9

// just authed with facebook, and I want to delete the first 3 rows of my 4 row table that are no longer necessary    
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
    if(wantsFacebook)
        return 1;

    return 4;
}

После выполнения обновлений tableView вызовет делегат numberOfRowsInSection, чтобы получить обновленное количество строк, и он ДОЛЖЕН быть правильной суммой/разницей между строками при запуске вставки/удаления и строк, когда вы закончили вставку/удалить