質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.96%

swift tableViewのセル選択時の動作について

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 4,611

score 59

セルにはあらかじめ配列partに入れたstring型の文字を表示しています。
この時セルを選択した時にそのセルの文字を配列passの文字に変えたいのですがこのプログラムではできませんでした。
また再度セルを選択した時にその文字がpassならpartをpartならpassを表示するようにコードを記述しました

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell:UITableViewCell=tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
if cell.textLabel!.text==part[indexPath.row]{
cell.textLabel!.text=pass[indexPath.row]
}else{
cell.textLabel!.text=part[indexPath.row]
}
}

セル選択時に何も起こらずただセルがグレーになるだけでした
解決方法を教えてくださいませんか

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

dequeueReusableCell()で返ってくるセルは表示されているセルではありません。表示を更新するために画面に表示中のセルを取得するにはcellForRow(at:)メソッドを使用します。

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)
    cell?.textLabel?.text = ...
}

ただし、ここで変更した内容は、このセルが画面外に出てセルが再利用されるときに失われますので、その場合でも状態を保持したい場合は、選択したという状態を保持して、func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCellメソッドで返すセルもその状態を反映する必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/08 21:38

    解決しました!
    ありがとうございます!

    キャンセル

0

選択した時の状態を保持したかったので、Structの配列でモデルを作成しました。
セルを選択した時に呼ばれるデリゲートメソッドdidSelectRowAtでモデルの選択状態を変更して リロードすると文字が変わります。

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    // Data Array
    var dataArray: Array<DataModel> = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // データを作成
        createData()

        tableView.estimatedRowHeight = 44
        tableView.rowHeight = UITableViewAutomaticDimension
    }

    func createData() {
        for i in 0...10 {
            dataArray.append(DataModel(part: "part -- \(String(i))", pass: "pass ** \(String(i))"))
        }
    }

    // MARK: - TableView Delegate & DataSource

    // Row Count
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArray.count
    }

    // Generate Cell
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let data = dataArray[indexPath.row]

        // データの選択状態でpartかpassの文字列を出し分ける
        cell.textLabel?.text = data.isSelectPass ? data.pass : data.part
        return cell
    }

    // Select Cell
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath as IndexPath, animated: true)

        // データの選択状態を変更してテーブルをリロード
        dataArray[indexPath.row].selectChange()
        tableView.reloadData()
    }
}


// partとpassを持つデータ
struct DataModel {

    var part: String!
    var pass: String!
    var isSelectPass = false

    init(part: String = "", pass: String = "", isSelectPass: Bool = false) {
        self.part = part
        self.pass = pass
        self.isSelectPass = isSelectPass
    }

    mutating func selectChange() {
        self.isSelectPass = !self.isSelectPass
    }
}

a

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/08 19:33

    すごい丁寧にありがとうございます。
    構造体を使ったやり方はとても参考になります。
    ちなみに私の書いたコードでは何がいけなかったかを教えてくださいませんか?
    テーブルをリロードしないと変化しないということでしょうか?

    キャンセル

  • 2016/10/08 19:54 編集

    セルは使いまわされているということはご存知ですか?下にスクロールした時に上に消えたセルが下から使いまわされて出てきます。
    cellForRowAtのメソッドの中で以下の文でセルのラベルのテキストを表示してみてください。
    print(cell.textLabel?.text)

    そうするとセルが表示された時に前の文字と違う文字のセルが渡されてくることが分かると思います。

    なので記載されているコードでは正確な判定ができないということです。

    キャンセル

  • 2016/10/08 21:39

    なるほど、、、
    参考になります!
    詳しい解説ありがとうございます

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.96%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る