2017-03-23 9 views
1

TableViewのセルに正しい選択状態が表示される正しい手順は何ですか?下の表は、UIButtonのサブクラスとして作成したカスタムインジケータを示しています。 didSelectRowAtIndexPathがタップされているとき、それらは点灯と消灯を切り替える。 tableViewのdataSourceは辞書の配列であり、辞書は各セルの状態に関する情報を保持しています。TableViewCellsを正しく更新する方法

私が解決しようとしている課題は、リストをスクロールするときに間違ったセルが点灯または消灯していることです。これはセルの再利用の機能と思われます。

enter image description here

私はwillDisplayCellForRowAtIndexPathのコードを入れて試してみました。私は前にこの問題を解決したと思うが、私はこの問題に固執している。ここで

は、カスタムボタンのクラス

import UIKit 

@IBDesignable 
class WaterButton: UIButton { 

    @IBInspectable var fillColor: UIColor = .green 
    @IBInspectable var greyColor: UIColor = .gray 
    @IBInspectable var completed = false 
    let lineWidth: CGFloat = 2.0 
    let π = CGFloat(M_PI) //option P for π 

    override func draw(_ rect: CGRect) { 
     if completed { 
      drawStrokedCircle(percentRadius:0.5, color: fillColor, filled: true) 
      drawStrokedCircle(percentRadius:0.8, color: fillColor, filled: false) 
     } else { 
      drawStrokedCircle(percentRadius:0.5, color: greyColor, filled: false) 
     } 
    } 

    func drawStrokedCircle(percentRadius: CGFloat, color: UIColor, filled: Bool) { 
     // 1 
     let center = CGPoint(x:bounds.width/2, y: bounds.height/2) 

     // 2 
     let radius: CGFloat = ((max(bounds.width, bounds.height)/2.0) * percentRadius) 

     // 3 
     //let arcWidth: CGFloat = 76 

     // 4 
     let startAngle: CGFloat = 0 
     let endAngle: CGFloat = 2 * π 

     // 5 
     let path = UIBezierPath(arcCenter: center, 
           radius: radius, 
           startAngle: startAngle, 
           endAngle: endAngle, 
           clockwise: true) 

     // 6 
     path.lineWidth = 2.0 
     color.setStroke() 
     path.stroke() 

     if filled { 
      fillColor.setFill() 
      path.fill() 
     } 
    } 
} 

答えて

0
私はまったく同じことをした

のtableView方法ここ

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = self.tableView.dequeueReusableCell(withIdentifier: "HourlyWaterCell", for: indexPath) as! HourlyWaterCell 
     let dictionary = dataSource[indexPath.row] 

     if let startTime = dictionary["startTime"] as! Date? { 
      cell.timeLabel.text = dateFormatter.string(from: startTime) 
     } 

     return cell 
    } 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 

    tableView.deselectRow(at: indexPath, animated: true) 
    var dictionary = dataSource[indexPath.row] 

    let buttonState = (tableView.cellForRow(at: indexPath) as! HourlyWaterCell).button.completed 
    if buttonState == true { 
     (tableView.cellForRow(at: indexPath) as! HourlyWaterCell).button.completed = false 
     cellStates[indexPath.row] = false 
     dictionary["selected"] = false 
    } 
    else { 
     (tableView.cellForRow(at: indexPath) as! HourlyWaterCell).button.completed = true 
     //cellStates[indexPath.row] = true 
     dictionary["selected"] = true 

     graphView.fill(column: 1) 
    } 

} 

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 

    let dictionary = self.dataSource[indexPath.row] 
    if let selectionState = dictionary["selected"] as! Bool? { 
     if selectionState == true{ 
      //cell.button.completed = true 
      cell.setSelected(true, animated: true) 
     } else { 
      //cell.button.completed = false 
      cell.setSelected(false, animated: true) 
     } 
    } 
} 

とされているが、それはしばらく前にあると私はアクセスできません。もうコードに

しかし、私はwillDisplayメソッドで選択を設定しませんでした。代わりにcellForRowAtに選択状態を設定しました。

また、テーブルビューのセル内でセルが選択されている場合は、私は簿記を実装しなければならなかったかもしれません。お役に立てれば!

:)

0

あなたは、ボタンの状態をあなたのボタンを保持しているセルがdequedされるたびに(cellForRowAtIndexPath)を復元し、その後、あなたの代理人であなたのWaterButtonの選択状態(completed)を保存することができます。あなたのWaterButtonであなたの '完了'プロパティの値の変化を観察してください。

@IBInspectable var completed = false { 
    didSet { 
     if completed == true { 
      drawStrokedCircle(percentRadius:0.5, color: fillColor, filled: true) 
      drawStrokedCircle(percentRadius:0.8, color: fillColor, filled: false) 
     } else { 
      drawStrokedCircle(percentRadius:0.5, color: greyColor, filled: false) 
     } 
    } 
} 

復元: あなたのテーブルビューのデリゲートにIVARを追加します。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
/* you can perform extra evaluation to avoid 
iterating to cellButtonStates if not needed */ 
    for (i,_) in self.cellButtonStates.keys.enumerated() { 
     self.cellButtonStates[i] = false 
    } 
    self.cellButtonStates[indexPath.row] = true 
    //call reloadData 
} 
:あなたは cellButtonStates毎回ユーザーがセルを選択を更新する必要が明らかに

var cellButtonStates : [NSInteger : Bool]?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "HourlyWaterCell", for: indexPath) as! HourlyWaterCell 
    let dictionary = dataSource[indexPath.row] 
    if let completed = cellButtonStates?[indexPath.row] { 
     cell.button.completed = completed 
    } 
} 

stiにする場合(isSelectedを使用して)あなたのコードを持つckが、私はあなたが以下のようなあなたのHourlyWaterCellにisSelectedプロパティをオーバーライドするお勧め:上記のコードの

class HourlyWaterCell: UITableViewCell { 
override var isSelected: Bool { 
    didSet { 
     button.completed = isSelected; 
    } 
} 

どれもテストされていません。

+0

ありがとうございます。残念ながら、それは動作しません。 – Aaronium112

関連する問題