393

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

Question:

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.

Answer1:

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 <a href="https://github.com/vinbhai4u/sampletablereuse" rel="nofollow">sampleTableReuse</a>

Answer2:

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])

Recommend

  • What is the TickFrequency equivalent of slider in silverlight
  • An object reference is required for the nonstatic field, method, or property 'member'
  • can't set JPanel color and JRadioButton invisibility
  • Android View setActive, setSelected and RecyclerView States
  • Why is PyQt connect() syntax so verbose?
  • UICollectionView Enable deselecting cells while allowsMultipleSelection is disabled
  • UIRefreshControl with low height UICollectionView
  • Highlight ListView item at creation time via code
  • .NET Text To Speech Volume
  • Why is my segue causing an “unrecognized selector sent to instance” NSInvalidArgumentException?
  • Swift Cast Generics Type
  • Google App Indexing not resolving for Swift?
  • Auto Height of UICollectionView inside UITableViewCell
  • “[CALayer release]: message sent to deallocated instance” when dismissing modal view controller
  • iOS 9 errors and correct conversion to swift 2
  • Generate a unique string based on a pair of strings
  • “A GKScore must specify a leaderboard.”
  • Deleting a widget from QTableView
  • Jquery UI Sortable, move item automatically
  • How to access recipient on sent messages page with mailboxer
  • multidatatrigger with multibinding in ControlTemplate.Triggers
  • Is there a parser equivalent of 'fragment' marking in ANTLR4?
  • Configure Spring's MappingJacksonHttpMessageConverter
  • Click on button in another program - FindWindow, C#
  • How do I retrieve the user information of a user authenticated with Apache's mod_ldap?
  • How can I restyle a word when rendering a pdf with pdf.js?
  • How to access profile picture with Facebook API in Swift 3?
  • Image map in Flex
  • Who propagate bugfixes across branches (corporate development)?
  • Build Successful but not running on simulator
  • How do I configure context broker accept post requests from my remote sensor?
  • c# open webrowser in many tab
  • MySQL Order by column = x, column asc?
  • custom UITableViewCell with image for highlighting
  • How to Cache Real-time Data?
  • swift auto completion not working in Xcode6-Beta
  • AT Commands to Send SMS not working in Windows 8.1
  • How to stop GridView from loading again when I press back button?
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • How to push additional view controllers onto NavigationController but keep the TabBar?