-1

iOS/Swift では、Client クラスの clientName プロパティに基づいて、インデックス付きの「クライアント」UITableView を作成しました。A から Z までをセクションとして辞書を作成しました。インデックス付きテーブルビューはうまく機能します。ただし、ユーザーが行を選択したときに、元のソース配列にある行を特定する方法を見つけようとしています。辞書がセクションに一致するようにソートされることを除いて、ある種の相互参照配列を構築することを考えていたので、どのセクション/行の組み合わせがどの元の配列エントリに一致するかわかりません。この問題を処理するための一般的なアプローチはありますか?

明らかにしようとして...

class Client {
    var clientId             : Int!
    var firstName            : String!
    var lastName             : String!
    var email                : String!
    var phone                : String!
    ...

    init() {

    }
}

var clients: [Client] = []

// clients array loaded from web service
...

// Create dictionary to be source for indexed tableview
func createClientDict() {
    clientDict          = [String: [String]]()
    clientSectionTitles = [String]()

    var clientNames:[String] = []
    for i in 0..<clients.count {
        let client = clients[i]

        let clientName = "\(client.lastName), \(client.firstName)"
        clientNames.append(clientName)
    }

    for name in clientNames {
        var client: Client  = Client()

        // Get the first letter of the name and build the dictionary
        let clientKey = name.substringToIndex(name.startIndex.advancedBy(1))
        if var clientValues = clientDict[clientKey] {
            clientValues.append(name)
            clientDict[clientKey] = clientValues
        } else {
            clientDict[clientKey] = [name]
        }
    }

    // Get the section titles from the dictionary's keys and sort them in ascending order
    clientSectionTitles = [String](clientDict.keys)
    clientSectionTitles = clientSectionTitles.sort { $0 < $1 }
}

これで、ユーザーがテーブルビューの行をタップすると、セクションと行 (indexPath) を取得できます。ただし、重複した名前がある可能性があると仮定して、クライアント配列のどの行が一致するかをどのように判断できますか? その場でソース配列の行にマップされたインデックス付きセクション/行の相互参照を作成する方法はありますか? ディクショナリの作成中にそれを実行しようとしましたが、ディクショナリは後でソートされるため、一致するものは何もありませんでした。たぶん、ソース行番号を辞書に/辞書に含める必要がありますか??

テーブルビューのコードは次のとおりです。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! ClientCell

    let clientKey = clientSectionTitles[indexPath.section]
    if let clientValues = clientDict[clientKey] {
        cell.clientName.text = clientValues[indexPath.row]
    }

    return cell
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return clientSectionTitles.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let clientKey = clientSectionTitles[section]
    if let clientValues = clientDict[clientKey] {
        return clientValues.count
    }

    return 0
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return clientSectionTitles[section]
}

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
    return clientIndexTitles
}

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {

    guard let index = clientSectionTitles.indexOf(title) else {
        return -1
    }

    return index
}

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 20
}

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    let headerView   = view as! UITableViewHeaderFooterView

    headerView.contentView.backgroundColor = UIColor ( red: 0.0, green: 0.3294, blue: 0.6392, alpha: 1.0 )
    headerView.textLabel?.textColor = UIColor.greenColor()
    headerView.textLabel?.font = UIFont(name: "Noteworthy-bold", size: 15.0)
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    selectedIndex = indexPath

    // In the following prepare for segue, I need to somehow use the selected indexpath to find the correct entry
    // in the clients array and pass it along.

    performSegueWithIdentifier("clientDetailSegue", sender: self)
}
4

1 に答える 1

0

私はそれを考え出した。ディクショナリ内の任意のクラスの配列をネストできることを (最近試してみるまで) 知りませんでした。クライアント配列をネストするように辞書を変更すると、すべてが解決されました。以下に示すように関数を変更しました。

func createClientDict() {
    // Declared for view controller. Re-initialized here.
    clientDict          = [String: [Client]]()
    clientSectionTitles = [String]()

    clients.sortInPlace ({ $0.lastName < $1.lastName })

    for c in clients {
        let clientName = "\(c.lastName), \(c.firstName)"

        // Get the first letter of the name and build the dictionary
        let clientKey = clientName!.substringToIndex(clientName!.startIndex.advancedBy(1))
        if var clientValues = clientDict[clientKey] {
            clientValues.append(c)
            clientDict[clientKey] = clientValues
        } else {
            clientDict[clientKey] = [c]
        }
    }

    // Get the section titles from the dictionary's keys and sort them in ascending order
    clientSectionTitles = [String](clientDict.keys)
    clientSectionTitles = clientSectionTitles.sort { $0 < $1 }
}

ただし、次の行が解決の鍵でした。

let clientDict = [String: [Client]]()
于 2016-03-22T05:15:51.497 に答える