iOS,在tableView单元格中加载的图表也会在另一个单元格中加载?

时间:2017-08-08 17:22:50

标签: ios swift uitableview subview

所以我有一个tableView,每个单元格中都有一组按钮。这些是用户投票的选项。

TableView with options

当用户按下某个选项时,会加载一个显示投票结果的图表。

Poll results after button pressed

然而,当我向下滚动时,图表在另一个tableView单元格上显得莫名其妙。该单元格中没有任何按钮被按下。此外,图表在第二个单元格中加载第一个数据。我被困在这几个小时,不知道为什么会这样。

enter image description here

编辑:这是tableView

的代码
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "pollCell") as! PollCell

let titled = titles[indexPath.row]
    cell.configure(polltitled: titled, num: indexPath.row)

return cell
}

以下是Poll Cell的方法:

var ref = FIRDatabase.database().reference()

var options = [String]()
var counts = [Int]()

self.loadedChart = false

@IBOutlet weak var chart: HorizontalBarChartView!

func configure(polltitled: String, num: Int) {

    self.pollTitle.text = polltitled
    self.row = num
    self.runRemove() { (success) -> Void in
        if success {
            if (loadedChart == false) {
                self.loadChart()
            }
        }
        else {

        }
        }
}

func runRemove(completion:(_ success: Bool) -> Void) {
        self.pollTitle.tag = 999
        self.chart.tag = 998

        for object in self.contentView.subviews {
            if ((object.tag != 999)  && (object.tag != 998)) {
                object.removeFromSuperview()

                }

    }

        completion(true)
}

func loadChart(){
    ref.child("poll").child(StaticVariables.currentEventQR).child(self.pollTitle.text!).observe(.value) { (snapshot: FIRDataSnapshot!) in


        self.counts.removeAll()
        self.options.removeAll()
        for item in snapshot.children {

            let childSnapshot = snapshot.childSnapshot(forPath: (item as AnyObject).key)

            let option = childSnapshot.key

            self.options.append(option)

        }
        self.loadCounts()
        self.createButtons()
    }

}

func loadCounts() {

    for i in self.options {
        self.ref.child("poll").child(StaticVariables.currentEventQR).child(self.pollTitle.text!).child(i).observe(.value) { (snapshot: FIRDataSnapshot!) in

            for item in snapshot.children {

                    let childSnapshot = snapshot.childSnapshot(forPath: (item as AnyObject).key)

                    let countsValue = childSnapshot.value as? NSDictionary
                    let count = countsValue?["Counter"] as! Int
                    self.counts.append(count)


            }

        }


    }




}

func createButtons() {
    var i = 1
    var height = 0
    if ((self.pollTitle.text?.characters.count)! > 37){
        height = 22
    }
    for option in self.options{
        let btn: UIButton = UIButton(frame: CGRect(x: Int(self.contentView.frame.size.width - 320)/2, y: 59+60*(i-1)+height, width: 320, height: 33))
        if ((i)%2 == 1){
            btn.backgroundColor = UIColor.init(red: 253/255, green: 185/255, blue: 39/255, alpha: 1.0)
        } else {
            btn.backgroundColor = UIColor.init(red: 0/255, green: 107/255, blue: 182/255, alpha: 1.0)
        }

        btn.addTarget(self, action: #selector(PollCell.optionOne(_:)), for: .touchUpInside)
        btn.tag = i
        self.contentView.addSubview(btn)
        btn.setTitle(option, for: .normal)
        i += 1

    }
}

@IBAction func optionOne(_ sender: UIButton) {
    self.loadedChart = true
    delegate.refresh(self.row)
    self.options.reverse()
    self.counts.reverse()
    self.setChart(dataPoints: self.options, values: self.counts)
    ref.child("poll").child(StaticVariables.currentEventQR).child(pollTitle.text!).child((sender.titleLabel?.text!)!).observeSingleEvent(of: .value, with: { (snapshot) in


        let item = snapshot.children.allObjects[0]
        let childSnapshot = snapshot.childSnapshot(forPath: (item as AnyObject).key)

        let responseID = childSnapshot.key
        let reponseValue = childSnapshot.value as? NSDictionary
        var response = reponseValue?["Counter"] as! Int
        response += 1
        self.ref.child("poll").child(StaticVariables.currentEventQR).child(self.pollTitle.text!).child((sender.titleLabel?.text!)!).child("count").setValue(["Counter": response])

    })
    self.contentView.bringSubview(toFront: self.chart)

}


func setChart(dataPoints: [String], values: [Int]) {

    self.chartHeight.constant = CGFloat((RowHeightCounter.sharedInstance.counters[row])*62+39)

    chart.chartDescription?.text = ""
    chart.noDataText = ""
    var dataEntries: [BarChartDataEntry] = []

    for i in 0..<dataPoints.count {
        let dataEntry = BarChartDataEntry(x: Double(i), y: Double(counts[i]))
        dataEntries.append(dataEntry)
    }

    let chartDataSet = BarChartDataSet(values: dataEntries, label: "Votes")
    let chartData = BarChartData(dataSet: chartDataSet)
    chart.data = chartData
    chart.xAxis.valueFormatter = IndexAxisValueFormatter(values: options)

    chart.xAxis.granularity = 1
    self.chart.alpha = 1.0
    chart.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .easeInBounce)

}

1 个答案:

答案 0 :(得分:0)

问题是UITableView重复使用单元格而不是一直创建新单元格。如果表中有足够的行,则会在滚动时看到该图表出现多次。

将图表添加到单元格后,它一直存在,直到被删除,因此每次再次使用该单元格时,图表就会存在。

UITableViewCell有一个方便的方法,当它即将被重用时被prepareForReuse()。实现此方法并重置单元格中需要重置的任何内容,然后再次出现。

这意味着您可能需要重新考虑单元格和数据源之间的接口。也许创建一个模型对象,其中包含问题和结果数据以及用户是否回答了问题。然后,数据源可以保存一系列问题并将正确的问题传递给每个单元格。然后,单元格可以根据问题

进行自我配置

另外,在从问题更改为结果时,我不会删除各种视图。我会在一个容器视图中包含所有问题,在另一个容器视图中包含所有图表。然后我会根据需要在两个容器上设置isHidden。这将使您的滚动帧速率更高。