UITableView
установить в статические ячейки.
Можно ли программно скрыть некоторые ячейки?
ios
objective-c
uitableview
Shmidt
источник
источник
IBOutletCollection
но я не вижу, как это повлияет на разницу. Я только вчера загрузил код, поэтому не думаю, что это старая версия.Чтобы скрыть статические ячейки в UITable:
В вашем классе делегата контроллера UITableView:
Objective-C:
Swift:
Этот метод будет вызываться для каждой ячейки в UITable. После вызова ячейки, которую вы хотите скрыть, мы устанавливаем ее высоту равной 0. Мы идентифицируем целевую ячейку, создав для нее выход:
источник
ClipToBounds
проблемы, вы также можете сделать ячейку скрытой. Мне это показалось бы чище. ;-)Лучший способ, как описано в следующем блоге http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/
источник
Мое решение идет в том же направлении, что и Гарет, хотя кое-что я делаю иначе.
Поехали:
1. Скройте ячейки
Нет возможности напрямую скрыть ячейки.
UITableViewController
- это источник данных, который предоставляет статические ячейки, и в настоящее время нет способа сказать ему «не предоставлять ячейку x». Таким образом, мы должны предоставить собственный источник данных, который делегирует функцииUITableViewController
объекту для получения статических ячеек.Проще всего создать подкласс
UITableViewController
и переопределить все методы, которые должны вести себя по-другому при скрытии ячеек .В простейшем случае (таблица с одним разделом, все ячейки имеют одинаковую высоту) это будет выглядеть так:
Если в вашей таблице несколько разделов или ячейки имеют разную высоту, вам необходимо переопределить другие методы. Здесь применяется тот же принцип: вам нужно сместить indexPath, section и row перед делегированием super.
Также имейте в виду, что параметр indexPath для таких методов, как
didSelectRowAtIndexPath:
будет отличаться для одной и той же ячейки в зависимости от состояния (т. Количества скрытых ячеек). Поэтому, вероятно, будет хорошей идеей всегда смещать любой параметр indexPath и работать с этими значениями.2. Анимируйте изменение
Как уже сказал Гарет, вы получаете серьезные сбои, если вы анимируете изменения, используя
reloadSections:withRowAnimation:
метод.Я обнаружил, что если вы позвоните
reloadData:
сразу после этого, анимация значительно улучшится (остались только незначительные глюки). После анимации таблица отображается правильно.Итак, что я делаю, это:
источник
numberOfRowsInSection:
вызывается только при первой загрузке таблицы. Когда я вызываю [self.tableView reloadData] - меняnumberOfRowsInSection:
больше не вызывают. ТолькоcellForRowAtIndexPath:
называется. Чего мне не хватает?cellOneOutlet.hidden = true
теперь переопределите метод ниже, проверьте, какой статус ячейки скрыт, и верните высоту 0 для этих ячеек. Это один из многих способов скрыть любую ячейку в статическом tableView в swift.
источник
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
. Я предполагаю, что он заменен наlet tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)
.UITableViewController
, у меня нетUITableView
методов делегатов.heightForRow
Нужны ли мне и другие методы, чтобы вызвать его?Я придумал альтернативу, которая фактически скрывает разделы и не удаляет их. Я попробовал подход @ henning77, но продолжал сталкиваться с проблемами, когда менял количество разделов статического UITableView. Этот метод мне очень понравился, но я в первую очередь пытаюсь скрыть разделы, а не строки. Я удаляю некоторые строки на лету, но это намного сложнее, поэтому я попытался сгруппировать вещи в секции, которые мне нужно показать или скрыть. Вот пример того, как я скрываю разделы:
Сначала я объявляю свойство NSMutableArray
В viewDidLoad (или после того, как вы запросили свои данные) вы можете добавить разделы, которые вы хотите скрыть в массив.
Затем реализуйте следующие методы делегата TableView
Затем установите высоту верхнего и нижнего колонтитула на 1 для скрытых разделов, потому что вы не можете установить высоту на 0. Это приводит к дополнительному 2 пиксельному пространству, но мы можем компенсировать это, отрегулировав высоту следующего видимого заголовка.
Затем, если у вас есть определенные строки, которые нужно скрыть, вы можете настроить numberOfRowsInSection и то, какие строки возвращаются в cellForRowAtIndexPath. В этом примере у меня есть раздел с тремя строками, любые три из которых могут быть пустыми и должны быть удалены.
Используйте этот offsetIndexPath для вычисления indexPath для строк, из которых вы условно удаляете строки. Не требуется, если вы только скрываете разделы
Есть много методов для переопределения, но что мне нравится в этом подходе, так это то, что его можно использовать повторно. Настройте массив hiddenSections, добавьте к нему, и он скроет правильные разделы. Скрыть ряды немного сложнее, но возможно. Мы не можем просто установить высоту строк, которые мы хотим скрыть, равной 0, если мы используем сгруппированный UITableView, потому что границы не будут отображаться правильно.
источник
NSMutableSet
дляhiddenSections
вместо. Это намного быстрее, поскольку вы в основном тестируете членство.NSMutableSet
для использования forhiddenSections
, хотя я понимаю, что суть вашего ответа была более концептуальной, чем придирчивой, относительно того, какой тип структуры данных вы должны использовать.Оказывается, вы можете скрывать и отображать ячейки в статическом UITableView - и с анимацией. И это не так уж и сложно.
Демо-проект
Видео демонстрационного проекта
Суть:
Use tableView:heightForRowAtIndexPath:
для динамического определения высоты ячеек на основе некоторого состояния.tableView.beginUpdates();tableView.endUpdates()
tableView.cellForRowAtIndexPath:
заходите внутрьtableView:heightForRowAtIndexPath:
. Используйте кэшированные indexPaths, чтобы различать ячейки.Больше информации в моем блоге (русский язык)
источник
Да, это определенно возможно, хотя сейчас я борюсь с той же проблемой. Мне удалось заставить клетки спрятаться, и все работает нормально, но в настоящее время я не могу аккуратно оживить их. Вот что я нашел:
Я скрываю строки в зависимости от состояния переключателя ВКЛ / ВЫКЛ в первой строке первого раздела. Если переключатель находится в положении ON, под ним в том же разделе находится 1 строка, в противном случае - 2 разные строки.
У меня есть селектор, вызываемый при переключении переключателя, и я устанавливаю переменную, чтобы указать, в каком состоянии я нахожусь. Затем я вызываю:
Я переопределяю функцию tableView: willDisplayCell: forRowAtIndexPath: и, если ячейка должна быть скрыта, я делаю следующее:
Это скрывает ячейку и ее содержимое, но не удаляет занимаемое ею пространство.
Чтобы удалить пробел, переопределите 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:
источник
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 или беспорядок с ограничениями автоматического макета, не работали для меня из-за проблем с автоматическим макетом. Код стал невыносимым.
Для простой статической таблицы мне лучше всего было:
Вот пример из моего контроллера табличного представления:
источник
Простой метод, совместимый с iOS 11 и IB / раскадровкой
Для iOS 11 я обнаружил, что модифицированная версия лучше всего ответа Мохамеда Салеха с некоторыми улучшениями, основанными на документации Apple. Он прекрасно анимируется, избегает уродливых взломов или жестко запрограммированных значений и использует высоту строк, уже установленную в Interface Builder. .
Основная идея состоит в том, чтобы установить высоту строки равной 0 для любых скрытых строк. Тогда используйте
tableView.performBatchUpdates
для запуска анимации, которая работает стабильно.Установите высоту ячейки
Вы хотите убедиться,
cellIsHidden
иindexPathOfHiddenCell
правильно настроены на ваш случай использования. Для моего кода они являются свойствами моего контроллера табличного представления.Переключение ячейки
В любом методе управления видимостью (вероятно, с помощью кнопки или
didSelectRow
) переключите состояние cellIsHidden внутриperformBatchUpdates
блока:Apple рекомендует
performBatchUpdates
большеbeginUpdates
иendUpdates
всегда, когда это возможно.источник
Я нашел решение для анимации скрытых ячеек в статической таблице.
Требуется только один дополнительный словарь:
И посмотрите на реализацию MyTableViewController. Нам нужны два метода для преобразования indexPath между видимым и невидимым индексами ...
Одно действие IBAction при изменении значения UISwitch:
Некоторые методы UITableViewDataSource и UITableViewDelegate:
источник
Ответь в кратчайшие сроки :
Добавьте следующий метод в свой TableViewController:
если tableView пытается нарисовать ячейку, которую вы хотите скрыть, он не будет отображаться, потому что его высота будет установлена на 0pt благодаря описанному выше методу, все остальное остается неизменным.
Обратите внимание, что
indexPathOfCellYouWantToHide
можно изменить в любой момент :)источник
В> Swift 2.2 я собрал здесь несколько ответов.
Сделайте выход из раскадровки для ссылки на свой staticCell.
Я хочу скрыть свою первую ячейку, поэтому установил высоту 0, как описано выше.
источник
Свифт 4:
источник
В самом простом сценарии, когда вы скрываете ячейки в самом низу представления таблицы, вы можете настроить tableView contentInset после того, как скроете ячейку:
источник
Это новый способ сделать это с помощью https://github.com/k06a/ABStaticTableViewController.
источник
Решение от k06a ( https://github.com/k06a/ABStaticTableViewController ) лучше, потому что оно скрывает весь раздел, включая верхние и нижние колонтитулы ячеек, где это решение ( https://github.com/peterpaulis/StaticDataTableViewController ) скрывает все, кроме нижнего колонтитула.
РЕДАКТИРОВАТЬ
Я только что нашел решение, если вы хотите скрыть нижний колонтитул
StaticDataTableViewController
. Вот что вам нужно скопировать в файл StaticTableViewController.m:источник
Конечно можно. Во-первых, вернитесь к вашему tableView количество ячеек, которое вы хотите показать, затем вызовите
super
для достижения определенной ячейки из вашей раскадровки и верните ее для tableView:Если у ваших ячеек другая высота, верните и ее:
источник
В дополнение к решению @Saleh Masum:
Если вы получаете ошибки автоматического макета , вы можете просто удалить ограничения из
tableViewCell.contentView
Свифт 3:
Это решение зависит от потока вашего приложения . Если вы хотите показать / скрыть ячейку в том же экземпляре контроллера представления, это может быть не лучшим выбором, поскольку он снимает ограничения .
источник
У меня появился лучший способ динамически скрывать статические ячейки и даже разделы без каких-либо взломов.
Установка высоты строки на 0 может скрыть строку, но это не сработает, если вы хотите скрыть весь раздел, который будет содержать некоторые пробелы, даже если вы скрываете все строки.
Мой подход заключается в создании массива секций статических ячеек. Тогда содержимое табличного представления будет управляться массивом разделов.
Вот пример кода:
Таким образом, вы можете собрать весь свой код конфигурации без необходимости написания неприятного кода для вычисления количества строк и разделов. И конечно нет
0
высот.Этот код также очень легко поддерживать. Например, если вы хотите добавить / удалить больше ячеек или разделов.
Аналогично, вы можете создать массив заголовков разделов и массив заголовков нижнего колонтитула раздела, чтобы динамически конфигурировать заголовки разделов.
источник