2017-01-27 8 views
0

JSONを呼び出して配列にデータを保存した後、tableViewをリロードした後、dequeueReusableCellを使用すると、すべてが機能しますが、cellForRowに変更すると、設定するたびにクラッシュします細胞。 CellForRowを使用している理由は、ユーザーがクリックした後にセルの画像を変更する必要があることです。ただし、dequeueReusableCellを使用すると、セルが常に再利用されるため、複数の変更があります。cellForRowはnil-swiftを返します。

私はlet cell = tableView.cellForRow(at: indexPath) as! TicketTableViewCellでクラッシュしています。私はすでに検索を行ったが、何も助けなかった。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.cellForRow(at: indexPath) as! TicketTableViewCell 

    //let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TicketTableViewCell 

    cell.date.text = arrDate[indexPath.row].date 

    //Top Bottom Space. 
    let maskLayer = CAShapeLayer() 
    let bounds = cell.bounds 
    maskLayer.path = UIBezierPath(roundedRect: CGRect(x: 2, y: 2, width: bounds.width-4, height: bounds.height-4), cornerRadius: 2).cgPath 
    cell.layer.mask = maskLayer 

    return cell 
} 
+2

明らかに、そのセルが 'indexPath'に追加されないので、あなたにはnilが与えられます。あなたは' dequeueReusableCell'を使う必要があります。あなたの質問で再利用の問題を追加する必要があります。 –

+0

'cellForRowAt'では' dequeueReusableCell'を、別の場所では 'cellForRow'を使うべきです。 – kennytm

答えて

1

インデックスパスがある場合は、テーブルビューからセルを取得することを意味します。テーブルビューのビューを再利用することはできません。再利用するには、デキューを使用する必要があります。

「セルが常に再利用されるため、複数の変更が発生する」という問題がある場合は、セルが再利用のために適切に準備されていること、および/またはセットアップが1回だけであることを確認する必要があります。

あなたの実装が何であるか分かりませんが、ユーザーがボタンまたはジェスチャ認識器からセルをクリックしたビューコントローラが呼び出されたときに、セル自体を渡す必要があります。 tableview.indexPathForCell()と呼び出すことができ、どのindexPathがクリックされたかを知ることができるので、このセルを更新するデータを知ることができます。お役に立てれば。

EDIT:(セルは、セルのselectedプロパティではなく、使用する場合はトラックを保存するという意味で「選択」されています)。また、選択したセルを画面外にスクロールして、それを選択する必要がある場合は、現在選択されているインデックスを追跡して、データソースメソッドでセルを別の方法でフォーマットする必要があります。

データソースメソッドを使用すると、セルが選択されているかどうかを確認することが重要です。これは、変更があると思われるセルを無差別にリロードすることができるためです。しかし、それは素晴らしいプラクティスではありませんが(シンプルで上質です)、セルを持っていればプロパティを直接設定できます。

+0

問題は、最後のセルイメージを変更できないことです。ユーザがセルA(画像の変化)をクリックしてからセルBをクリックすると、セルAはそれ以上選択されていないので、デフォルト画像を取得するはずである。ユーザーがセルをクリックするたびに、変数にindexPathを保存します。別のセルをクリックすると、変数を使用してセルの画像を元の状態に戻しますが、これは機能しません。 – Adrian

+0

あなたが説明したことはこれと互換性があるはずです。あなたが説明したことはうまくいくと思いますが、コードを見る必要があります。他のすべてのセルをデフォルトに戻したいのであれば、一般的な方法は、表示されているセル、 'tableView.visibleCells {'のセルをループし、すべてをデフォルトに設定してから、別の値を設定することです。次に、以前に選択されたセルを追跡する必要はありません。 –

+1

OK - 前の行もリロードするだけで、再描画され、selectedIndexが異なることを確認してデフォルトのイメージを使用します。 セルを更新するために 'cellForRowAt'にいくつかのコードを追加したら、それを行います。 didSelectメソッドの一部としてイメージを直接更新している場合は、それを取り出し、selectedIndexを更新して、現在と前の(存在する場合) – Russell

2

を確認してくださいdidSelectRowAt変更に使用したい画像をdequeueReusableCell

の使用に戻る、またはあなたのデータセット内のどこかに値を設定し、その行をリロードすることcellForRowAt方法更新したイメージまたはフラグを使用してセルを再描画します。第2の方法は、ちょうどあなたが戻っ以前に最初の方法でそれを与えた細胞を与えるので、あなたがtableView.cellForRow(at: indexPath)を使用することはできませんtableView(:cellForRowAt:)データソースメソッド内から

+0

実際に私はそれをしますが、問題は私が最後の細胞画像を変更することができないということです。ユーザがセルA(画像の変化)をクリックしてからセルBをクリックすると、セルAはそれ以上選択されていないので、デフォルト画像を取得するはずである。ユーザーがセルをクリックするたびに、変数にindexPathを保存します。別のセルをクリックすると、変数を使用してセルの画像を元の状態に戻しますが、これは機能しません。 – Adrian

関連する問題