当tableview滚动时,UISegment值会发生变化

时间:2015-09-02 11:32:27

标签: swift uitableview uisegmentedcontrol

我正在使用UISegmentControl在表格视图中显示目标类型问题。但是,如果我在任何一个单元格中选择一个段,那么如果我滚动,则会更改某些段值。我不知道如何解决这个问题。 请指导我。

细胞大小: 160px

段色调颜色蓝色

编码

//UIViewController
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = segTblVw.dequeueReusableCellWithIdentifier("segment", forIndexPath: indexPath) as! segmentTblCell

        return cell
    }

//UITableViewCell CLASS
class segmentTblCell: UITableViewCell {



    @IBOutlet weak var segMent: UISegmentedControl!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

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

        // Configure the view for the selected state
    }

}

以下屏幕截图:

enter image description here

5 个答案:

答案 0 :(得分:2)

由于dequeueReusableCellWithIdentifier:的工作方式,您遇到了这个问题。每当一个单元格滚出屏幕时,它就会进入一个缓存区域,在那里它将被重用。

假设你有100个细胞。他们的所有segmentedControl个对象都设置为first。你点击一个来改变它的价值。当单元格移出视图时,它会进入缓存,如果您进一步向下滚动,它将在那里出列。

理解这一点很重要,因为segmentedControl对象实际上并没有改变。由于出列行为,它看起来正在改变。

要解决此问题,您需要实现一个存储segmentedControl对象值的dataSource,以便每次单元格出列时都可以正确重新初始化它。

答案 1 :(得分:1)

方法1:通过将所有单元格对象保存在数组中来防止单元格的可重用性

var arraysCells : NSMutableArray = []//globally declare this
viewDidLoad()

中的

for num in yourQuestionArray//this loop is to create all cells at beginning 
{
     var nib:Array = NSBundle.mainBundle().loadNibNamed("SegmentTableViewCell", owner: self, options: nil)
     var cell = nib[0] as? SegmentTableViewCell
     arraysCells.addObject(cell!);
}
tableViewDelegate中的

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return arraysCells.objectAtIndex(indexPath.row) as! UITableViewCell
}

您可以通过迭代arraysCells

找到所选的细分值(答案)
  

注意:如果您有大量的单元格,方法1将会很慢

方法2:正常重用单元格,但保存状态(输入值)使用委托和数组。

在自定义UITableViewCell

@objc protocol SegmentTableViewCellDelegate {
func controller(controller: SegmentTableViewCell, selectedSegmentIndex:Int, indexPath : NSIndexPath)
}

class SegmentTableViewCell: UITableViewCell {

var delegate: AnyObject?
var indexPath : NSIndexPath?

@IBOutlet weak var segment: UISegmentedControl! //outlet of segmented Control

@IBAction func onSegmentValueChanged(sender: UISegmentedControl/*if the parameter type is AnyObject changed it as  UISegmentedControl*/)//action for Segment
{
    self.delegate?.controller(self, selectedSegmentIndex: sender.selectedSegmentIndex, indexPath: indexPath!)
}
在viewController中

class MasterViewController: SegmentTableViewCellDelegate{
var selectedAnswerIndex : NSMutableArray = []  //globally declare this
var selectedSegmentsIndexPath : NSMutableArray = [] //globally declare this


func controller(controller: SegmentTableViewCell, selectedSegmentIndex:Int, indexPath : NSIndexPath)
{
    if(selectedSegmentsIndexPath.containsObject(indexPath))
    {
        selectedAnswerIndex.removeObjectAtIndex(selectedSegmentsIndexPath.indexOfObject(indexPath))
        selectedSegmentsIndexPath.removeObject(indexPath)
    }
    selectedAnswerIndex.addObject(selectedSegmentIndex)
    selectedSegmentsIndexPath.addObject(indexPath)
}

in cellForRowAtIndexPath(tableView Delegate)

if(selectedSegmentsIndexPath.containsObject(indexPath))
{
 cell?.segment.selectedSegmentIndex = selectedAnswerIndex.objectAtIndex(selectedSegmentsIndexPath.indexOfObject(indexPath)) as! Int
}
cell?.delegate = self
cell?.indexPath = indexPath

你可以通过

获得结果
for index in selectedSegmentsIndexPath
{
  var  cellIndexPath = index as! NSIndexPath
  var answer : Int = selectedAnswerIndex.objectAtIndex(selectedSegmentsIndexPath.indexOfObject(cellIndexPath)) as! Int
  NSLog("You have enterd answer \(answer) for question number \(cellIndexPath.row)")
}

答案 2 :(得分:0)

@KelvinLau是完美的

你可以使用var segmentedTracker : [NSIndexPath:Int] = [:]

来做到这一点

on segmentedValueChanged设置selectedIndex的值,即:segmentedTracker[indexPath] = valueOf the selected index

然后在cellForRowAtIndexPath中检查值let selected = [segmentedTracker]

cell.yourSegmentedControlReference.selectedIndex = selected

请注意这是一个伪代码,我不记得属性名称。从这里你可以自己解决

答案 3 :(得分:0)

我认为在UITableViewCell中使用UISegmentControl可能是错误的。

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISegmentedControl_Class/

我从未在iOS应用程序中看到过这种情况。

问题是dequeueReusableCellWithIdentifier方法重用UITableViewCell。因此,滚动时会更改一些UISegmentControl值。

虽然这不是最佳解决方案,但您可以使用静态单元格。你需要做的是只切换静态单元格。如果是这样,你不会编写UITableViewCell的代码。

enter image description here

答案 4 :(得分:0)

2018年:更新答案

在此UISegement inside UITableViewCell

中找到我最简单的答案

=============================================== ======

2015年

我已经以自己的方式进行了测试。我的编码如下。请指导我,无论是正确还是错误的方式?我的问题得到了解决。此代码停止可重复使用的单元格。

我的编码如下:

//UIViewController
var globalCell = segmentTblCell()  //CUSTOM UITableViewCell Class

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = segTblVw.dequeueReusableCellWithIdentifier("segment", forIndexPath: indexPath) as! segmentTblCell

    globalCell  = segTblVw.dequeueReusableCellWithIdentifier("segment", forIndexPath: indexPath) as! segmentTblCell  //THIS LINE - STOPS REUSABLE TABLE.

    return cell
}