UISegment value changing when tableview get scrolled
Method 1: Prevent reusability of cells by, Holding all cell objects in an array
var arraysCells : NSMutableArray = []//globally declare this
in 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!);
}
in tableViewDelegate,
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return arraysCells.objectAtIndex(indexPath.row) as! UITableViewCell
}
you can find the selected segment values (answer) by iterating arraysCells
NOTE: Method 1 will be slow, if you have big number of cells
Method 2: Reuse the cell as normal, but save the states(enterd values) Using Delegate and arrays.
in custom 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!)
}
in 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
you can get the result by
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)")
}
UITableView: reloadRows(at:) takes two hits for table to be updated and scroll every time
Your UISegmentedControl
are reusing [Default behaviour of UITableView].
To avoid that, keep dictionary
for getting and storing values.
Another thing, try outlet connection as Action
for UISegmentedControl
in UIViewController
itself, instead of your UITableViewCell
The below code will not reload your tableview when you tap UISegmentedControl
. You can avoid, delegates call too.
Below codes are basic demo for UISegmentedControl
. Do customise as per your need.
var segmentDict = [Int : Int]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...29 // number of rows count
{
segmentDict[i] = 0 //DEFAULT SELECTED SEGMENTS
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SOTableViewCell
cell.mySegment.selectedSegmentIndex = segmentDict[indexPath.row]!
cell.selectionStyle = .none
return cell
}
@IBAction func mySegmentAcn(_ sender: UISegmentedControl) {
let cellPosition = sender.convert(CGPoint.zero, to: tblVw)
let indPath = tblVw.indexPathForRow(at: cellPosition)
segmentDict[(indPath?.row)!] = sender.selectedSegmentIndex
print("Sender.tag ", indPath)
}
Why is scrolling performance poor for custom table view cells having UISegmentedControl objects?
Any drawing that a table cell has to do while it's being scrolled is going to cause performance issues; when you have a lot of subviews, there tends to be a lot of drawing going on, and that will—as you've observed—make your scrolling pretty choppy. There are a couple of ways to try to reduce that.
The first step is to make sure that your cells themselves, and as many of their subviews as possible, have their opaque
properties set to YES
. Opaque views don't have to get blended with the content underneath them, and that saves a lot of time.
You may also want to set your cells' layers to rasterize themselves, like this:
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
This will collapse your view hierarchy into one flat bitmap, which is the kind of thing Core Animation just loves to draw. Note that any animating views—activity indicators, for instance—will force that bitmap to be updated every time they change, i.e. a lot. In that case, you won't want the cell to rasterize everything; you might just use a subview with all of your relatively static views (e.g. labels) beneath another subview with any such dynamic content, and only have the first of those rasterized.
How do I keep the selected segment of UISegmentedControl inside UITableView when cell is reused?
Your model for each row should have a property that keeps the selected segment, lets call it selectedSegment
. When the user clicks on a segment you affect the value of the selectedSegment
property for the instance of the object representing the affected row.
Then in your cellForRowAtIndexPath:
method, you update the UISegmentedControl's selected index with the value of the selectedSegment
property.
Related Topics
iOS Firebase: Firauthuidelegate.Authui Not Being Called
Sort Dictionary Keys by Value, Then by Key
Disable Https Get Certificate Check in Swift 5
How to Rotate an Object Around Only One Axis in Realitykit
JSONencoder Won't Allow Type Encoded to Primitive Value
Encoding Swift String as Escaped Unicode
Correct Way to Use Nwconnection for Long-Running Tcp Socket
Cloudkit - "Invalid Bundle Id for Container"
Get Nil When Looking for File in Subdirectory of Main Bundle
Swiftui on MACos - Handle Single-Click and Double-Click at the Same Time
Swift. Declaring Private Functions in Internal Protocol
Same Class Extension in Two Different Modules
Testing If a Decimal Is a Whole Number in Swift
Swift Nsusernotification Doesn't Show While App Is Active