人の詳細を表示するアプリがあるとしましょう。各人は、0個以上の電話番号と0個以上のメモを添付できます。したがって、Person
エンティティおよびPhone
エンティティと1対多の関係を持つCoreDataエンティティNote
があります。これらをUITableView
に表示します。「電話」というセクションと「メモ」というセクションが1つずつあります。
したがって、numberOfRowsInSection
は次のようになります。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0: // Phones
if self.person.phones.count > 0 {
return self.person.phones.count
} else {
return 1 // We want a different cell to display "no phones"
}
case 1: // Notes
if self.person.notes.count > 0 {
return self.person.notes.count
} else {
return 1 // We want a different cell to display "no notes"
default:
return 0
}
}
そして、cellForRowAt
は次のようになります:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
if self.person.phones.count > 0 {
return UITableViewCell.init(style: .default, reuseIdentifier: "PhoneNumberCell")
} else {
return UITableViewCell.init(style: .default, reuseIdentifier: "NoPhoneNumbersCell")
}
case 1:
if self.person.notes.count > 0 {
return UITableViewCell.init(style: .default, reuseIdentifier: "NoteCell")
} else {
return UITableViewCell.init(style: .default, reuseIdentifier: "NoNotesCell")
}
default:
return UITableViewCell.init(style: .default, reuseIdentifier: "default")
}
}
そして、すでに推測できるように、同じコードがwillDisplay
に対して繰り返されます。
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
switch indexPath.section {
case 0:
if self.person.phones.count > 0 {
// Configure Phone Cell
} else {
// Configure No Phones Cell
}
case 1:
if self.person.notes.count > 0 {
// Configure Note Cell
} else {
// Configure No Notes Cell
}
default: break
}
}
同じことがdidSelectRowAt
(および他のデリゲート/データソースメソッド)にも当てはまりますが、ここではこれ以上コピーしません。
私がやりたいのは、この長くて繰り返されるswitch
をif..else
ステートメントで取り除くことですが、問題は、それを使用して数値を返す場合もあれば、文字列を返す場合もあれば、セルを構成するだけです。
この場合に推奨するアイデアやパターンはありますか?
これがあなたの例のために私が見たいデータソースの種類です:
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].itemCount
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return sections[indexPath.section].cell(forRow: indexPath.row)
}
上記を機能させるには、Section
プロトコルが必要です。
protocol Section {
var itemCount: Int { get }
var cell(forRow row: Int) -> UITableViewCell
}
...また、そのプロトコルを実装するPhoneNumberSection
とNoteSection
もあります。