Я бы рекомендовал использовать оба, если вы используете динамически генерируемый контент. В противном случае ваше приложение может неожиданно зависнуть. Вы можете реализовать свою собственную функцию для извлечения дополнительной многократно используемой ячейки. Если это так, nil
вы должны вернуть пустую ячейку, которая не видна:
Swift 3
// Extensions to UITableView
extension UITableView
{
// returns nil, if identifier does not exist.
// Otherwise it returns a configured cell for the given index path
open func tryDequeueReusableCell (
withIdentifier identifier: String,
for indexPath: IndexPath) -> UITableViewCell?
{
let cell = self.dequeueReusableCell(withIdentifier: identifier)
if cell != nil {
return self.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
}
return nil
}
}
И расширение для возврата пустой ячейки:
// Extension to UITableViewCell
extension UITableViewCell
{
// Generates an empty table cell that is not visible
class func empty() -> UITableViewCell
{
let emptyCell = UITableViewCell(frame:CGRect(x:0, y:0, width:0, height:0))
emptyCell.backgroundColor = UIColor.clear
return emptyCell
}
}
Полный пример того, как его использовать:
import Foundation
import UIKit
// A protocol is used to identify if we can configure
// a cell with CellData
protocol ConfigureAbleWithCellData
{
func configure(_ data: CellData)
}
class MyCustomTableViewCell :
UITableViewCell,
ConfigureAbleWithCellData
{
@IBOutlet weak var title:UILabel! = nil
func configure(_ data: CellData)
{
self.title.text = data.title
}
}
// This actually holds the data for one cell
struct CellData
{
var title:String = ""
var reusableId:String = ""
}
class CosmoConverterUnitTableViewController:
UIViewController,
UITableViewDelegate,
UITableViewDataSource
{
// Storage
var data = Array<Array<CellData>>()
func loadData()
{
var section1:[CellData] = []
var section2:[CellData] = []
section1.append(CellData(title:"Foo", reusableId:"cellType1"))
section2.append(CellData(title:"Bar", reusableId:"cellType2"))
data.append(section1)
data.append(section2)
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
{
return data[section].count
}
public func numberOfSections(in tableView: UITableView) -> Int
{
return data.count
}
func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard
indexPath.row < data[indexPath.section].count
else
{
fatalError("this can't be")
}
let cellData = data[indexPath.section][indexPath.row]
if let cell = tableView.tryDequeueReusableCell(
withIdentifier: cellData.reusableId,
for: indexPath)
{
if let configurableCell = cell as? ConfigureAbleWithCellData
{
configurableCell.configure(cellData)
}
else
{
// cell is not of type ConfigureAbleWithCellData
// so we cant configure it.
}
return cell
}
// id does not exist
return UITableViewCell.empty()
}
}