Swift: Segmented control behaves in a weird way in UITableView Cell

社会主义新天地 提交于 2019-12-10 12:17:26

问题


Anytime I tap segmented control in UICell, immediately some other cell gets this segmented control in the same position. It looks like segmented control recognizes that not only this particular one was tapped but also some other one in other cell.

Have you ever encountered issue like this?

this is my custom cell implementation:

class QuestionYesNoCustomCellTableViewCell: UITableViewCell {

@IBOutlet weak var questionLabel: UILabel!
@IBOutlet weak var segmentControl: ADVSegmentedControl!
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    segmentControl.items = ["TAK", "NIE"]
    segmentControl.font = UIFont(name: "Avenir-Black", size: 12)
    segmentControl.borderColor = UIColor.grayColor()
    segmentControl.selectedIndex = 1
    segmentControl.selectedLabelColor = UIColor.whiteColor()
    segmentControl.unselectedLabelColor = UIColor.grayColor()
    segmentControl.thumbColor = UIColor(red: 46.0/255.0, green: 204.0/255.0, blue: 113.0/255.0, alpha: 1.0)
    segmentControl.addTarget(self, action: "segmentValueChanged:", forControlEvents: .ValueChanged)
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}



func segmentValueChanged(sender: AnyObject?){


    if segmentControl.selectedIndex == 0 {

        segmentControl.thumbColor = UIColor(red: 231.0/255.0, green: 76.0/255.0, blue: 60.0/255.0, alpha: 1.0)
        segmentControl.selectedLabelColor = UIColor.whiteColor()
        segmentControl.unselectedLabelColor = UIColor.grayColor()

    }else if segmentControl.selectedIndex == 1{

        segmentControl.thumbColor = UIColor(red: 46.0/255.0, green: 204.0/255.0, blue: 113.0/255.0, alpha: 1.0)
        segmentControl.selectedLabelColor = UIColor.grayColor()
        segmentControl.unselectedLabelColor = UIColor.whiteColor()
    }

}

Also, I think it is worth to provide my tableView delegate methods implemented

 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {



    return (dict2 as NSDictionary).objectForKey(dictKeysSorted[section])!.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: QuestionYesNoCustomCellTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! QuestionYesNoCustomCellTableViewCell


    cell.questionLabel.text = (dict2 as NSDictionary).objectForKey(dictKeysSorted[indexPath.section])![indexPath.row] as? String
    if indexPath.row % 2 == 0 {
        cell.backgroundColor = UIColor(red: 245.0/255.0, green: 245.0/255.0, blue: 245.0/255.0, alpha: 1.0)
    }
    else {
        cell.backgroundColor = UIColor(red: 225.0/255.0, green: 225.0/255.0, blue: 225.0/255.0, alpha: 0.7)

    }


    return cell


}

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

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let headerCell = tableView.dequeueReusableCellWithIdentifier("CellHeader") as! CustomHeaderCell

            headerCell.backgroundColor = UIColor(red: 20.0/255.0, green: 159.0/255.0, blue: 198.0/255.0, alpha: 1.0)
    headerCell.headerLabel.text = dictKeysSorted[section]
    return headerCell
}

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

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

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 110.0
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

To recap what the problem actually is: In every tableView cell there is a segment control. When I change the position of the one located in first row, I scroll down and see that segment control in row 5 also has been moved despite the fact it should be in the default position.

Thanks in advance

EDIT:

I recognized one of the biggest problem in solutions below - they are good as long as you don't use section in tableView. The thing is, from what I have discovered right now, in each sections the rows are counted over from 0.


回答1:


This might be the cause when you are using reusing the cells, when you scroll the cell you changed will be shown again for another row.

To avoid this when you reuse cell make sure you reset the data in it also

In your case you have to check if the segmented value is changed then change the segmented control value also in cellForRowAtIndexPath

Please let me know if you need more explanation.

Here is a sample project for you sampleTableReuse




回答2:


It's because of reusable nature of UITableViewCells. You must keep track in your datasource selected segment index for each row. Then in cellForRowAtIndexPath you must set it properly for each cell.

example

define somewhere an enum with possible Answers:

enum Answer {
    case Yes
    case No
    case None
}

then define and init your answers' array:

var answer = [Answer](count: numberOfQuestions, repeatedValue: .None)

in your cell's implementation add a method to configure a cell with Answer

func setupWithAnswer(answer: Answer)
{
    var selectedIdex = UISegmentedControlNoSegment
    switch answer {
        case .Yes: selectedIdex = 0
        case .No: selectedIdex = 1
        default: break
    }
    self.segmentedControl.selectedSegmentIndex = selectedIdex
}

and finally, in your cellForRowAtIndex do after dequeuing

cell.setupWithAnswer(answer: self.answers[indexPath.row])


来源:https://stackoverflow.com/questions/33364419/swift-segmented-control-behaves-in-a-weird-way-in-uitableview-cell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!