web-dev-qa-db-ja.com

異なる方法で使用するメソッドで条件を繰り返さないようにするにはどうすればよいですか?

人の詳細を表示するアプリがあるとしましょう。各人は、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(および他のデリゲート/データソースメソッド)にも当てはまりますが、ここではこれ以上コピーしません。

私がやりたいのは、この長くて繰り返されるswitchif..elseステートメントで取り除くことですが、問題は、それを使用して数値を返す場合もあれば、文字列を返す場合もあれば、セルを構成するだけです。

この場合に推奨するアイデアやパターンはありますか?

2
phi

これがあなたの例のために私が見たいデータソースの種類です:

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 
}

...また、そのプロトコルを実装するPhoneNumberSectionNoteSectionもあります。

1
Daniel T.