unable to save on/off state of a UITableViewCell?
In Swift the most efficient way is a callback closure.
In the cell add a property callback
with a closure passing a Bool
value and no return value. Call the callback when the value of the switch changed.
class TableViewCell: UITableViewCell {
@IBOutlet weak var timeLbl: UILabel!
@IBOutlet weak var switchBtn: UISwitch!
var alarm = Bool()
var callback : ((Bool) -> Void)?
@IBAction func valChange(_ sender: UISwitch) {
callback?(sender.isOn)
}
}
In cellForRow
in the controller add the callback, in the closure update the model.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell
let item = items[indexPath.row]
cell.timeLbl.text = item.time
cell.switchBtn.isOn = item.isOn
cell.callback = { newValue in
self.items[indexPath.row].isOn = newValue
}
return cell
}
If cells can be inserted, deleted or moved you have to pass also the cell to get the actual index path
class TableViewCell: UITableViewCell {
@IBOutlet weak var timeLbl: UILabel!
@IBOutlet weak var switchBtn: UISwitch!
var alarm = Bool()
var callback : ((UITableViewCell, Bool) -> Void)?
@IBAction func valChange(_ sender: UISwitch) {
callback?(self, sender.isOn)
}
}
and
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell
let item = items[indexPath.row]
cell.timeLbl.text = item.time
cell.switchBtn.isOn = item.isOn
cell.callback = { currentCell, newValue in
let currentIndexPath = tableView.indexPath(for: currentCell)!
self.items[currentIndexPath.row].isOn = newValue
}
return cell
}
How to save the state of UITableViewCell accessory checkmark in Swift 3
Create a class variable of type IndexPath. In your cellForRowAt method set .checkmark accessory type only if index path matches the class variable and .none otherwise. In didSelectRowAt method update the indexPath of selected variable and just reload the tableview
UISwitch in custom UITableViewCell Reuse Issue
I would recommend to you create cellViewModel class and keep array of it instead of just string. You cellViewModel may look like,
class CellViewModel {
let title: String
var isOn: Bool
init(withText text: String, isOn: Bool = false /* you can keep is at by default false*/) {
self.title = text
self.isOn = isOn
}
Now, build array of CellViewModel
let array =["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
var cellViewModels = [CellViewModel]()
for text in array {
let cellViewModel = CellViewModel(withText: text)
cellViewModels.append(cellViewModel)
}
Change your tableVieDelegate function to :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
let cellViewModel = cellViewModels[indexPath.row]
cell.label.text = cellViewModel.title
cell.toggleSwitch.isOn = cellViewModel.isOn
cell.delegate = self
return cell
}
In you Custom Cell class, add this protocol :
protocol CellActionDelegate: class {
func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell)
}
Add delegate as property in your custom cell,
weak var delegate: CellActionDelegate?
Also, on switch change, add this line,
delegate?.didChangeSwitchStateOnCell(self)
Now, your viewController should register and listen to this delegate :
I have added line cellForRowAtIndexPath to register for delegates. To listen this delegate, add this function in your VC.
func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell) {
let indexPath = tableView.indexPath(for: cell)
cellViewModels[indexPath.row].isOn = cell.toggleSwitch.isOn
}
How to retrieve UISwitch state in each of my UITableView cells?
You save that value just like any other value you use in a table view -- in an array that's your data source. Given what you show in your image, your data source should be an array of dictionaries with keys for the menu item, price, and switch state. In cellForRowAtIndexPath, you would set the state of the switch based on the value ( a BOOL) in your array.
UITableViewCell subview disappears when cell is selected
UITableViewCell
changes the background color of all sub views when cell is selected or highlighted ,You can Solve this problem by overriding Tableview cell's setSelected:animated
and setHighlighted:animated
and resetting view background color.
In Objective C :
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
UIColor *color = self.yourView.backgroundColor;
[super setSelected:selected animated:animated];
if (selected){
self.yourView.backgroundColor = color;
}
}
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
UIColor *color = self.yourView.backgroundColor;
[super setHighlighted:highlighted animated:animated];
if (highlighted){
self.yourView.backgroundColor = color;
}
}
In Swift 3.1 :
override func setSelected(_ selected: Bool, animated: Bool) {
let color = yourView.backgroundColor
super.setSelected(selected, animated: animated)
if selected {
yourView.backgroundColor = color
}
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
let color = yourView.backgroundColor
super.setHighlighted(highlighted, animated: animated)
if highlighted {
yourView.backgroundColor = color
}
}
Is it possible to prevent uitableviewcell to unload on device rotation?
I think you cannot prevent reusing. You can reuse cell's smart (for example, save cell's content before rotation / restore after rotation). For right positioning:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)io
{
[self saveContentOfCells:[self.tableView indexPathsOfVisibleCells]];
self.lastVisible = [[self.tableView indexPathsOfVisibleCells] lastObject];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)io
{
[self.tableView scrollToRowAtIndexPath:self.lastVisible atScrollPosition:UITableViewScrollPositionBottom];
}
- (UITableViewCell*)tableView:(UITableView*)tv cellForRowAtIndexPath:(NSIndexPath*)ip
{
// dequeue cell
// try to restore content if any, clear restoration info
// if no restoration info setup cell
// return cell
}
Related Topics
Find Multiple Quoted Words in a String with Regex
Nothing Prints Out in the Console in Command Line Tool Xcode
How to Make a Button Have a Rounded Border in Swift
Expand and Contract Tableview Cell When Tapped, in Swift
How to Get Multiple Lines of Stdin Swift Hackerrank
How to Set Font Size of Sklabelnode to Fit in Fixed Size (Swift)
How to Increase (Animate) the Width of the Square on Both Ends
How to Distinguish Between Multiple Uipickerviews on One Page
Xcode 6.3 Code Completion Too Slow
How to Make a Swift Enum with Associated Values Equatable
Create an Outlet in Storyboard to an Inherited Property
Swift: Set Insertion Point in Nstextfield
How to Make an Enum Conform to a Protocol in Swift
How to Find Max Value for Double and Float in Swift
Delegate Methods in Child Class Sometimes Not Called with Swift 5 Compiler
Custom UI Tableviewcell Selected Backgroundcolor Swift