Відповіді:
Ви шукаєте це рішення:
StaticDataTableViewController 2.0
https://github.com/xelvenone/StaticDataTableViewController
яка може показувати / приховувати / перезавантажувати будь-які статичні комірки з анімацією або без неї!
[self cell:self.outletToMyStaticCell1 setHidden:hide];
[self cell:self.outletToMyStaticCell2 setHidden:hide];
[self reloadDataAnimated:YES];
Зауважте, що завжди використовувати лише (reloadDataAnimated: ТАК / НІ) (не дзвоніть [self.tableView reloadData] безпосередньо)
Це не використовує хакі-рішення із встановленням висоти 0 і дозволяє анімувати зміни та приховувати цілі секції
IBOutletCollection
але я не бачу, як це може змінити ситуацію. Я завантажив код лише вчора, тому не думаю, що це стара версія.
Щоб приховати статичні комірки в UITable:
У вашому класі делегата контролера UITableView:
Завдання-C:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if(cell == self.cellYouWantToHide)
return 0; //set the hidden cell's height to 0
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
Швидкий:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
if cell == self.cellYouWantToHide {
return 0
}
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
Цей метод буде викликаний для кожної комірки в UITable. Після того, як він називає його для комірки, яку ви хочете приховати, ми встановлюємо її висоту на 0. Ми визначаємо цільову клітинку, створюючи для неї розетку:
ClipToBounds
проблеми, ви також можете встановити клітинку на приховану. Мені це здасться чистішим. ;-)
Найкращий спосіб описаний у наступному блозі http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/
Створіть свій перегляд статичної таблиці як звичайний для побудови інтерфейсу - у комплекті з усіма потенційно прихованими клітинками. Але є одне, що ви повинні зробити для кожної потенційної комірки, яку ви хочете приховати, - перевірте властивість кліпу "Підвідмірки" клітини, інакше вміст комірки не зникне при спробі приховати її (зменшуючи висоту - ще пізніше).
Так - у вас є перемикач у комірці, і комутатор повинен ховати та показувати деякі статичні комірки. Підключіть це до IBAction і там зробіть це:
[self.tableView beginUpdates]; [self.tableView endUpdates];
Це дає вам приємну анімацію для клітин, які з’являються та зникають. Тепер застосуйте такий метод делегування подання таблиці:
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1 && indexPath.row == 1) { // This is the cell to hide - change as you need // Show or hide cell if (self.mySwitch.on) { return 44; // Show the cell - adjust the height as you need } else { return 0; // Hide the cell } } return 44; }
І це все. Перемістіть перемикач, і комірка ховається і знову з’являється з приємною, плавною анімацією.
Моє рішення йде в аналогічний напрям, як Гарет, хоча деякі речі я роблю інакше.
Ось:
1. Сховати клітини
Немає можливості безпосередньо приховати клітини. UITableViewController
є джерелом даних, яке забезпечує статичні комірки, і в даний час немає способу сказати це "не надавати клітинку x". Тож ми маємо надати власне джерело даних, яке делегує UITableViewController
, щоб отримати статичні комірки.
Найпростіше - це підклас UITableViewController
та перекриття всіх методів, які повинні поводитися по-різному, приховуючи клітини .
У найпростішому випадку (таблиця з одним розділом, всі осередки мають однакову висоту), це піде так:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [super tableView:tableView numberOfRowsInSection:section] - numberOfCellsHidden;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Recalculate indexPath based on hidden cells
indexPath = [self offsetIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (NSIndexPath*)offsetIndexPath:(NSIndexPath*)indexPath
{
int offsetSection = indexPath.section; // Also offset section if you intend to hide whole sections
int numberOfCellsHiddenAbove = ... // Calculate how many cells are hidden above the given indexPath.row
int offsetRow = indexPath.row + numberOfCellsHiddenAbove;
return [NSIndexPath indexPathForRow:offsetRow inSection:offsetSection];
}
Якщо у вашій таблиці є декілька розділів або комірки мають різну висоту, вам потрібно змінити більше методів. Тут застосовується той самий принцип: Вам потрібно зрушити indexPath, розділ і рядок перед делегацією в super.
Також майте на увазі, що параметр indexPath для подібних методів didSelectRowAtIndexPath:
буде різним для однієї комірки, залежно від стану (тобто кількості прихованих комірок). Тому, мабуть, є хорошою ідеєю завжди компенсувати будь-який параметр indexPath і працювати з цими значеннями.
2. Анімувати зміни
Як уже заявив Гарет, ви отримуєте основні проблеми, якщо анімувати зміни за допомогою reloadSections:withRowAnimation:
методу.
Я дізнався, що якщо ви reloadData:
відразу зателефонуєте , анімація значно покращиться (залишилися лише незначні глюки). Таблиця відображається правильно після анімації.
Отже, що я роблю, це:
- (void)changeState
{
// Change state so cells are hidden/unhidden
...
// Reload all sections
NSIndexSet* reloadSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self numberOfSectionsInTableView:tableView])];
[tableView reloadSections:reloadSet withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadData];
}
numberOfRowsInSection:
викликаються лише при першому завантаженні таблиці. Коли я дзвоню [self.tableView reloadData] - numberOfRowsInSection:
більше ніколи не дзвоню . Тільки cellForRowAtIndexPath:
називається. Що я пропускаю?
cellOneOutlet.hidden = вірно
тепер замініть нижченаведений метод, перевірте, який стан комірки приховано, і поверніть висоту 0 для цих комірок. Це один з багатьох способів швидко приховати будь-яку клітинку в статичну tableView.
override func tableView(tableView: UITableView, heightForRowAtIndexPathindexPath: NSIndexPath) -> CGFloat
{
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
if tableViewCell.hidden == true
{
return 0
}
else{
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
}
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
. Я припускаю, що це замінено на let tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)
.
UITableViewController
, я не маю жодних UITableView
методів делегування. Для того, щоб змусити його зателефонувати heightForRow
, чи потрібно також використовувати інші методи?
Я придумав альтернативу, яка фактично приховує розділи та не видаляє їх. Я спробував підхід @ henning77, але в мене виникли проблеми, коли я змінив кількість розділів статичного UITableView. Цей метод спрацював для мене дуже добре, але я в першу чергу намагаюся приховати розділи замість рядків. Я ледь вдало видаляю рядки, але це набагато грізніше, тому я спробував згрупувати речі в розділи, які мені потрібно показати або приховати. Ось приклад того, як я приховую розділи:
Спочатку я оголошую властивість NSMutableArray
@property (nonatomic, strong) NSMutableArray *hiddenSections;
У viewDidLoad (або після запиту даних) ви можете додати до масиву розділи, які ви хочете приховати.
- (void)viewDidLoad
{
hiddenSections = [NSMutableArray new];
if(some piece of data is empty){
// Add index of section that should be hidden
[self.hiddenSections addObject:[NSNumber numberWithInt:1]];
}
... add as many sections to the array as needed
[self.tableView reloadData];
}
Потім реалізуйте наступні методи делегування TableView
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return nil;
}
return [super tableView:tableView titleForHeaderInSection:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
return 0;
}
return [super tableView:tableView heightForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
[cell setHidden:YES];
}
}
Потім встановіть висоту заголовка та нижнього колонтитула на 1 для прихованих секцій, оскільки ви не можете встановити висоту до 0. Це спричиняє додатковий простір у 2 пікселі, але ми можемо компенсувати його, регулюючи висоту наступного видимого заголовка.
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
CGFloat height = [super tableView:tableView heightForHeaderInSection:section];
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
height = 1; // Can't be zero
}
else if([self tableView:tableView titleForHeaderInSection:section] == nil){ // Only adjust if title is nil
// Adjust height for previous hidden sections
CGFloat adjust = 0;
for(int i = (section - 1); i >= 0; i--){
if([self.hiddenSections containsObject:[NSNumber numberWithInt:i]]){
adjust = adjust + 2;
}
else {
break;
}
}
if(adjust > 0)
{
if(height == -1){
height = self.tableView.sectionHeaderHeight;
}
height = height - adjust;
if(height < 1){
height = 1;
}
}
}
return height;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
return 1;
}
return [super tableView:tableView heightForFooterInSection:section];
}
Потім, якщо у вас є конкретні рядки для приховування, ви можете відрегулювати числоOfRowsInSection і які рядки повертаються в cellForRowAtIndexPath. У цьому прикладі тут є розділ, який містить три рядки, де будь-які три можуть бути порожніми і їх потрібно видалити.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = [super tableView:tableView numberOfRowsInSection:section];
if(self.organization != nil){
if(section == 5){ // Contact
if([self.organization objectForKey:@"Phone"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"Email"] == [NSNull null]){
rows--;
}
if([self.organization objectForKey:@"City"] == [NSNull null]){
rows--;
}
}
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [super tableView:tableView cellForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}
Використовуйте цей offsetIndexPath для обчислення indexPath для рядків, де ви умовно видаляєте рядки. Не потрібен, якщо ви ховаєте лише секції
- (NSIndexPath *)offsetIndexPath:(NSIndexPath*)indexPath
{
int row = indexPath.row;
if(self.organization != nil){
if(indexPath.section == 5){
// Adjust row to return based on which rows before are hidden
if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
else if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Address"] != [NSNull null]){
row = row + 2;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] != [NSNull null] && [self.organization objectForKey:@"Email"] == [NSNull null]){
row++;
}
else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){
row++;
}
}
}
NSIndexPath *offsetPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];
return offsetPath;
}
Існує дуже багато методів переоцінки, але мені подобається цей підхід - це повторне використання. Налаштуйте масив hiddenSections, додайте до нього, і він приховає правильні розділи. Ховаючи ряди, це трохи хитріше, але можливо. Ми не можемо просто встановити висоту рядків, які ми хочемо приховати до 0, якщо ми використовуємо згрупований UITableView, оскільки межі не будуть виведені правильно.
NSMutableSet
для hiddenSections
замість. Це набагато швидше, оскільки ви в основному тестуєте на членство.
NSMutableSet
для hiddenSections
, хоча я розумію , що точка вашої відповіді , був більш концептуальним , ніж ніт-розбірливі в тому , який тип структури даних , ви повинні використовувати.
Виявляється, ви можете сховати і показати комірки в статичному UITableView - і з анімацією. І це не так важко здійснити.
Відео демонстраційного проекту
Суть:
Use tableView:heightForRowAtIndexPath:
щоб динамічно вказати висоту комірок на основі певного стану.tableView.beginUpdates();tableView.endUpdates()
tableView.cellForRowAtIndexPath:
всередину tableView:heightForRowAtIndexPath:
. Використовуйте кешовані indexPaths для диференціації комірок.Так, це, безумовно, можливо, хоча я зараз борюся з тим же питанням. Мені вдалося змусити клітинки приховати, і все працює нормально, але наразі я не можу зробити так, щоб річ анімувалась акуратно. Ось що я знайшов:
Я приховую рядки на основі стану вимикача ON / OFF у першому рядку першого розділу. Якщо перемикач увімкнено, під ним у цьому ж розділі знаходиться 1 ряд, інакше є 2 різних рядки.
У мене є селектор, який викликається, коли перемикач перемикається, і я встановлюю змінну, щоб вказати, у якому стані я перебуваю. Потім я закликаю:
[[self tableView] reloadData];
Я переосмислюю функцію tableView: willDisplayCell: forRowAtIndexPath: і якщо комірка повинна бути прихованою, я роблю це:
[cell setHidden:YES];
Це приховує клітинку та її вміст, але не прибирає місця, яке вона займає.
Щоб вилучити пробіл, замініть функцію tableView: heightForRowAtIndexPath: і поверніть 0 для рядків, які слід приховати.
Вам також потрібно замінити tableView: numberOfRowsInSection: і повернути кількість рядків у цьому розділі. Тут ви повинні зробити щось дивне, щоб, якщо ваш стіл є згрупованим стилем, закруглені кути трапляються на правильних клітинках. У моїй статичній таблиці є повний набір комірок для розділу, тому є перша комірка, що містить опцію, потім 1 комірка для параметрів стану ВКЛ та ще 2 комірки для опцій стану ВИМКН, загалом 4 комірки. Коли параметр увімкнено, мені потрібно повернути 4, сюди входить прихований варіант, щоб останній варіант, що відображається, мав закруглене поле. Коли параметр вимкнено, останні два варіанти не відображаються, тому я повертаюся 2. Це все відчуває незграбність. Вибачте, якщо це не дуже зрозуміло, його складно описати. Просто для ілюстрації налаштування, це побудова розділу таблиці в IB:
Отже, коли параметр увімкнено, таблиця повідомляє про два рядки, які є:
Якщо параметр ВИМКНЕНО, таблиця повідомляє про чотири рядки:
Цей підхід не вважається правильним з кількох причин - це так само, наскільки я мав свої експерименти досі, тому, будь ласка, повідомте мене, якщо ви знайдете кращий спосіб. Проблеми, які я спостерігав поки що:
Неправильно сказати таблиці, що кількість рядків відрізняється від того, що імовірно міститься в базових даних.
Я, здається, не можу оживити зміни. Я спробував використовувати tableView: reloadSections: withRowAnimation: замість reloadData і результати, здається, не мають сенсу, я все ще намагаюся налагодити це. Наразі, що здається, що tableView не оновлює правильні рядки, тому одна залишається прихованою, яку слід відобразити, а під першим рядком залишається порожнеча Я думаю, це може бути пов’язане з першим моментом про основні дані.
Сподіваємось, хтось зможе запропонувати альтернативні методи або, можливо, як продовжити анімацію, але, можливо, це змусить вас почати. Мої вибачення за відсутність гіперпосилань на функції, я вклав їх, але вони були відхилені фільтром спаму, оскільки я досить новий користувач.
[[self tableView] reloadData];
один раз, сховавши клітини
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
в UITableViewController
підкласі для створення статичних осередків.
Відповідно до відповіді Юстаса, але для Swift 4:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
if cell == self.cellYouWantToHide {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
tableView.reloadRows(at:, with:)
для оновлення комірок, якщо ви змінюєте висоту, поки рядок уже видно.
Гаразд, після деяких спроб у мене є не загальна відповідь. Я використовую змінну "isHidden" або "прихований", щоб перевірити, чи повинна ця клітинка бути прихованою.
створити IBOutlet для контролера перегляду.
@IBOutlet weak var myCell: UITableViewCell!
Оновіть myCell
у своїй спеціальній функції, наприклад, ви можете додати її у viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
self.myCell.isHidden = true
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
guard !cell.isHidden else {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
Це зменшить вашу логіку в методі делегування, і вам потрібно лише зосередитися на ваших бізнес-вимогах.
Наведені вище відповіді, які приховують / показують комірки, змінюють rowHeight або псують з обмеженнями автоматичного макета, не працювали для мене через проблеми з автоматичним компонуванням. Код став нестерпним.
Для простої статичної таблиці найкраще працювало:
Ось приклад з мого контролера подання таблиці:
@IBOutlet weak var titleCell: UITableViewCell!
@IBOutlet weak var nagCell: UITableViewCell!
@IBOutlet weak var categoryCell: UITableViewCell!
var cellsToShow: [UITableViewCell] = []
override func viewDidLoad() {
super.viewDidLoad()
determinCellsToShow()
}
func determinCellsToShow() {
if detail!.duration.type != nil {
cellsToShow = [titleCell, nagCell, categoryCell]
}
else {
cellsToShow = [titleCell, categoryCell]
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return cellsToShow[indexPath.row]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellsToShow.count
}
Для iOS 11 я виявив, що модифікована версія відповіді Мохамеда Салеха найкраще працює з деякими вдосконаленнями на основі документації Apple. Це добре анімує, уникає некрасивих хакерів або твердо кодованих значень і використовує висоти рядків, вже встановлені в Interface Builder .
Основна концепція - встановити висоту рядка на 0 для будь-яких прихованих рядків. Потім використовуйте tableView.performBatchUpdates
для запуску анімації, яка працює стабільно.
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == indexPathOfHiddenCell {
if cellIsHidden {
return 0
}
}
// Calling super will use the height set in your storyboard, avoiding hardcoded values
return super.tableView(tableView, heightForRowAt: indexPath)
}
Ви хочете, щоб переконатися, cellIsHidden
і indexPathOfHiddenCell
вони встановлені відповідно до вашої справи використання. Для мого коду вони є властивостями в моєму контролері подання таблиці.
За допомогою будь-якого способу контролю видимості (швидше за все, дії кнопки чи didSelectRow
), перемикайте стан cellIsHidden всередині performBatchUpdates
блоку:
tableView.performBatchUpdates({
// Use self to capture for block
self.cellIsHidden = !self.cellIsHidden
}, completion: nil)
Apple рекомендує performBatchUpdates
більше beginUpdates
/endUpdates
коли це можливо.
Я знайшов рішення для оживлених прихованих комірок у статичній таблиці.
// Class for wrapping Objective-C block
typedef BOOL (^HidableCellVisibilityFunctor)();
@interface BlockExecutor : NSObject
@property (strong,nonatomic) HidableCellVisibilityFunctor block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block;
@end
@implementation BlockExecutor
@synthesize block = _block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block
{
BlockExecutor * executor = [[BlockExecutor alloc] init];
executor.block = block;
return executor;
}
@end
Потрібен лише один додатковий словник:
@interface MyTableViewController ()
@property (nonatomic) NSMutableDictionary * hidableCellsDict;
@property (weak, nonatomic) IBOutlet UISwitch * birthdaySwitch;
@end
І подивіться на реалізацію MyTableViewController. Нам потрібні два методи для перетворення indexPath між видимими і невидимими індексами ...
- (NSIndexPath*)recoverIndexPath:(NSIndexPath *)indexPath
{
int rowDelta = 0;
for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
if (ip.section == indexPath.section
&& ip.row <= indexPath.row + rowDelta
&& !executor.block())
{
rowDelta++;
}
}
return [NSIndexPath indexPathForRow:indexPath.row+rowDelta inSection:indexPath.section];
}
- (NSIndexPath*)mapToNewIndexPath:(NSIndexPath *)indexPath
{
int rowDelta = 0;
for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
if (ip.section == indexPath.section
&& ip.row < indexPath.row - rowDelta
&& !executor.block())
{
rowDelta++;
}
}
return [NSIndexPath indexPathForRow:indexPath.row-rowDelta inSection:indexPath.section];
}
Зміна значення однієї IBA на UISwitch:
- (IBAction)birthdaySwitchChanged:(id)sender
{
NSIndexPath * indexPath = [self mapToNewIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
if (self.birthdaySwitch.on)
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
else
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Деякі методи UITableViewDataSource та UITableViewDelegate:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int numberOfRows = [super tableView:tableView numberOfRowsInSection:section];
for (NSIndexPath * indexPath in [self.hidableCellsDict allKeys])
if (indexPath.section == section)
{
BlockExecutor * executor = [self.hidableCellsDict objectForKey:indexPath];
numberOfRows -= (executor.block()?0:1);
}
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPath = [self recoverIndexPath:indexPath];
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPath = [self recoverIndexPath:indexPath];
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// initializing dictionary
self.hidableCellsDict = [NSMutableDictionary dictionary];
[self.hidableCellsDict setObject:[BlockExecutor executorWithBlock:^(){return self.birthdaySwitch.on;}] forKey:[NSIndexPath indexPathForRow:1 inSection:1]];
}
- (void)viewDidUnload
{
[self setBirthdaySwitch:nil];
[super viewDidUnload];
}
@end
Відповідь швидко :
Додайте такий спосіб у свій TableViewController:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return indexPathOfCellYouWantToHide == indexPath ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
якщо tableView намагається намалювати клітинку, яку ви хочете приховати, вона не відображатиме її, оскільки її висота буде встановлена на 0pt завдяки вищевказаному методу, все інше залишається незмінним.
Зверніть увагу, що indexPathOfCellYouWantToHide
можна змінити будь-коли :)
В> Швидкий 2.2, тут я поєднав кілька відповідей.
Зробіть розетку з рекламної плати, щоб зв’язатись із staticCell.
@IBOutlet weak var updateStaticCell: UITableViewCell!
override func viewDidLoad() {
...
updateStaticCell.hidden = true
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return 0
} else {
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}
}
Я хочу приховати свою першу комірку, щоб я встановив висоту 0, як описано вище.
Швидкий 4:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var height = super.tableView(tableView, heightForRowAt: indexPath)
if (indexPath.row == HIDDENROW) {
height = 0.0
}
return height
}
Для найпростішого сценарію, коли ви ховаєте комірки в самій нижній частині таблиці, ви можете скорегувати contentView contentVset після того, як приховати комірок:
- (void)adjustBottomInsetForHiddenSections:(NSInteger)numberOfHiddenSections
{
CGFloat bottomInset = numberOfHiddenSections * 44.0; // or any other 'magic number
self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, -bottomInset, self.tableView.contentInset.right);
}
Це новий спосіб зробити це за допомогою https://github.com/k06a/ABStaticTableViewController
NSIndexPath *ip = [NSIndexPath indexPathForRow:1 section:1];
[self deleteRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade]
Рішення від k06a ( https://github.com/k06a/ABStaticTableViewController ) краще, оскільки воно приховує цілий розділ, включаючи заголовки та колонтитули комірок, де це рішення ( https://github.com/peterpaulis/StaticDataTableViewController ) приховує все, крім колонтитулу.
EDIT
Щойно я знайшов рішення, якщо ви хочете приховати колонтитул StaticDataTableViewController
. Це те, що потрібно скопіювати у файл StaticTableViewController.m:
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {
return [super tableView:tableView titleForFooterInSection:section];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
CGFloat height = [super tableView:tableView heightForFooterInSection:section];
if (self.originalTable == nil) {
return height;
}
if (!self.hideSectionsWithHiddenRows) {
return height;
}
OriginalSection * os = self.originalTable.sections[section];
if ([os numberOfVissibleRows] == 0) {
//return 0;
return CGFLOAT_MIN;
} else {
return height;
}
//return 0;
return CGFLOAT_MIN;
}
Звичайно, ви можете. По-перше, поверніться до таблиці tableView кількість комірок, які ви хочете показати, а потім зателефонуйте, super
щоб досягти певної комірки з вашої табло та повернути її для tableView:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.mode.numberOfCells()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
return cell
}
Якщо ваші клітини мають різну захищеність, поверніть її також:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return super.tableView(tableView, heightForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
}
Окрім рішення @Saleh Masum:
Якщо ви отримаєте помилки автоматичного розміщення , ви можете просто усунути обмеження зtableViewCell.contentView
Швидкий 3:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let tableViewCell = super.tableView(tableView, cellForRowAt: indexPath)
if tableViewCell.isHidden == true
{
tableViewCell.contentView.removeConstraints(tableViewCell.contentView.constraints)
return 0
}
else{
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
Це рішення залежить від потоку вашої програми . Якщо ви хочете показати / приховати клітинку в одному екземплярі контролера представлення даних, це може бути не найкращим вибором, оскільки це знімає обмеження .
У мене є кращий спосіб динамічно приховати статичні комірки та навіть секції без будь-яких злому.
Якщо встановити висоту рядка в 0, можна приховати рядок, але це не спрацює, якщо ви хочете приховати цілий розділ, який буде містити деякі пробіли, навіть якщо ви ховаєте всі рядки.
Мій підхід полягає у створенні масиву секцій статичних комірок. Тоді вміст подання таблиці буде керуватися масивом розділів.
Ось приклад коду:
var tableSections = [[UITableViewCell]]()
private func configTableSections() {
// seciton A
tableSections.append([self.cell1InSectionA, self.cell2InSectionA])
// section B
if shouldShowSectionB {
tableSections.append([self.cell1InSectionB, self.cell2InSectionB])
}
// section C
if shouldShowCell1InSectionC {
tableSections.append([self.cell1InSectionC, self.cell2InSectionC, self.cell3InSectionC])
} else {
tableSections.append([self.cell2InSectionC, self.cell3InSectionC])
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return tableSections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableSections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableSections[indexPath.section][indexPath.row]
}
Таким чином, ви можете скласти весь свій конфігураційний код разом, не записуючи неприємний код, щоб обчислити кількість рядків і розділів. І звичайно, ні0
висоти.
Цей код також дуже простий у обслуговуванні. Наприклад, якщо ви хочете додати / видалити більше комірок або розділів.
Аналогічно, ви можете створити масив заголовка розділу та масив заголовків колонтитулу розділу, щоб динамічно конфігурувати заголовки розділу.