Swift:分段控件在 UITableView Cell 中的行为很奇怪
Swift: Segmented control behaves in a weird way in UITableView Cell
每当我在 UICell 中点击分段控件时,其他单元格会立即在同一位置获得该分段控件。看起来分段控件不仅可以识别这个特定的控件,还可以识别其他单元格中的其他控件。
你遇到过这样的问题吗?
这是我的自定义单元实现:
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()
}
}
此外,我认为提供已实现的 tableView 委托方法是值得的
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.
}
回顾一下实际问题是什么:在每个 tableView 单元格中都有一个段控件。当我更改位于第一行的位置时,我向下滚动并看到第 5 行中的段控件也已移动,尽管它应该处于默认位置。
提前致谢
编辑:
我认识到以下解决方案中最大的问题之一 - 只要您不在 tableView 中使用部分,它们就很好。问题是,根据我现在的发现,在每个部分中,行都是从 0 开始计算的。
这是因为 UITableViewCells 的可重用特性。您必须在数据源中为每一行选择的段索引进行跟踪。然后在 cellForRowAtIndexPath 中,您必须为每个单元格正确设置它。
例子
在某处定义一个可能的答案枚举:
enum Answer {
case Yes
case No
case None
}
然后定义并初始化你的答案数组:
var answer = [Answer](count: numberOfQuestions, repeatedValue: .None)
在您的单元格实现中添加一个方法来配置带有 Answer 的单元格
func setupWithAnswer(answer: Answer)
{
var selectedIdex = UISegmentedControlNoSegment
switch answer {
case .Yes: selectedIdex = 0
case .No: selectedIdex = 1
default: break
}
self.segmentedControl.selectedSegmentIndex = selectedIdex
}
最后,在您的 cellForRowAtIndex 中执行出列操作
cell.setupWithAnswer(answer: self.answers[indexPath.row])
这可能是当您重复使用单元格时的原因,当您滚动您更改的单元格时,将再次显示另一行。
要在重复使用单元格时避免这种情况,请确保还重置其中的数据
在您的情况下,您必须检查分段值是否已更改,然后还要在 cellForRowAtIndexPath 中更改分段控件值
如果您需要更多解释,请告诉我。
这是一个示例项目给你sampleTableReuse
每当我在 UICell 中点击分段控件时,其他单元格会立即在同一位置获得该分段控件。看起来分段控件不仅可以识别这个特定的控件,还可以识别其他单元格中的其他控件。
你遇到过这样的问题吗?
这是我的自定义单元实现:
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()
}
}
此外,我认为提供已实现的 tableView 委托方法是值得的
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.
}
回顾一下实际问题是什么:在每个 tableView 单元格中都有一个段控件。当我更改位于第一行的位置时,我向下滚动并看到第 5 行中的段控件也已移动,尽管它应该处于默认位置。
提前致谢
编辑:
我认识到以下解决方案中最大的问题之一 - 只要您不在 tableView 中使用部分,它们就很好。问题是,根据我现在的发现,在每个部分中,行都是从 0 开始计算的。
这是因为 UITableViewCells 的可重用特性。您必须在数据源中为每一行选择的段索引进行跟踪。然后在 cellForRowAtIndexPath 中,您必须为每个单元格正确设置它。
例子
在某处定义一个可能的答案枚举:
enum Answer {
case Yes
case No
case None
}
然后定义并初始化你的答案数组:
var answer = [Answer](count: numberOfQuestions, repeatedValue: .None)
在您的单元格实现中添加一个方法来配置带有 Answer 的单元格
func setupWithAnswer(answer: Answer)
{
var selectedIdex = UISegmentedControlNoSegment
switch answer {
case .Yes: selectedIdex = 0
case .No: selectedIdex = 1
default: break
}
self.segmentedControl.selectedSegmentIndex = selectedIdex
}
最后,在您的 cellForRowAtIndex 中执行出列操作
cell.setupWithAnswer(answer: self.answers[indexPath.row])
这可能是当您重复使用单元格时的原因,当您滚动您更改的单元格时,将再次显示另一行。
要在重复使用单元格时避免这种情况,请确保还重置其中的数据
在您的情况下,您必须检查分段值是否已更改,然后还要在 cellForRowAtIndexPath 中更改分段控件值
如果您需要更多解释,请告诉我。
这是一个示例项目给你sampleTableReuse