Я бы рекомендовал разрешить методам источника данных табличного представления работать с отфильтрованной версией timeline
.Однако не делайте этого в методе cellForRowAt
, потому что нам нужно сделать это один раз, но не для каждого рисунка ячейки.
Итак, вы можете объявить filteredTimeline
и выполнить фильтр один разв методе viewDidLoad
(например):
class TableViewController: UIViewController {
// ...
var filteredTimeline // as the same type of `timeline`
override func viewDidLoad() {
// ...
filteredTimeline = timeline?.postObjects?.filter{!($0.hidden ?? false)}
// ...
}
// Returning only the number of visible cells
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredTimeline.count ?? 0
}
// And creating cells for only visible rows
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let post = filteredTimeline?.postObjects?.filter{!($0.hidden ?? false)}[indexPath.row] {
return (tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell).with(post: post, timelineController: self, darkMode: isDarkMode())
}
}
// ...
}
В случае лучшего места для filteredTimeline = timeline?.postObjects?.filter{!($0.hidden ?? false)}
, чем viewDidLoad
, вам может потребоваться позвонить tableView.reloadData()
.
Альтернатива, которую вы можете сделать:
, если вы считаете, что вам не нужен оригинал timeline
, вы можете отфильтровать его сам:
timeline = timeline?.postObjects?.filter{!($0.hidden ?? false)}
tableView.reloadData()
и вам не понадобится дополнительный отфильтрованный массив.
Дополнительный совет:
В случае возврата 0.0
значения в методе heightForRowAt
для определенногострока cellForRowAt
даже не будет вызвана;Например:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.row == 0 ?? 0.0 : 100.0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ...
}
На этом этапе cellForRowAt
следует вызывать только один раз, поскольку высота для первого ряда 0.0
.