I'm trying to develop an app that has a similar look as the pictures that I have attached here, since I really like that Idea.
After selecting an item, it drops down and a clip starts playing
Any idea on how to implement this? I can work with tables and lists, but I have no idea on how to actually implement something like this.
You can achieve this with multiple ways
let indexPath = NSIndexPath(forRow: YourSelectedRow, inSection: 0)
tableView.insertRowsAtIndexPaths(indexPath, withRowAnimation: .none )
insert a different row here which will be tricky to manage.
Create all this headers and and create only one cell under selected section.
var selectedSection = -1
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50)
let button = UIButton(frame: view.frame)
button.tag = section
button.addTarget(self, action: #selector(selectExercise(_:), forControlEvents: UIControlEvents.TouchUpInside)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 5
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if section == selectedSection
{
return 1
}
else
{
return 0
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier(“YourDetailCell”, forIndexPath: indexPath) as! YourDetailCell
return cell
}
fun selectExercise(sender:UIButton)
{
selectedSection = sender.tag
}
Create two cells and change that specific cell with whole cell portion with animation
var selectedRow = -1
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if selectedRow == -1
{
selectedRow = indexPath.row
tblConfirmedServices.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Bottom)
}
else
{
selectedRow = - 1
tblConfirmedServices.reloadRowsAtIndexPaths([indexPathPre], withRowAnimation: .Top)
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
if selectedRow = indexPath.row
{
let cell = tableView.dequeueReusableCellWithIdentifier(“YourDetailCell”, forIndexPath: indexPath) as! YourDetailCell
return cell
}
else
{
let cell = tableView.dequeueReusableCellWithIdentifier(“YourCell”, forIndexPath: indexPath) as! YourCell
return cell
}
}
Related
This question already has answers here:
Issue Detecting Button cellForRowAt
(3 answers)
Closed 2 years ago.
Using this code i only get tag which has indexpath.row how to make a button event from it.
TaskPlayButton is my button on that i am passing indexpath.row
for single section this would have worked by now how to do on multiple section.
Is there any other way of knowing which button is clicked?
func numberOfSections(in tableView: UITableView) -> Int {
return mobileBrand.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mobileBrand[section].modelName?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell
cell.TaskName.text = mobileBrand[indexPath.section].modelName?[indexPath.row]
cell.TaskPlayButton.tag = indexPath.row
cell.TaskPlayButton.addTarget(self, action: #selector(PlayBtnClicked( _:)), for: UIButton.Event.touchUpInside)
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 40))
view.backgroundColor = UIColor.rgb(red: 245, green: 245, blue: 245)
let lbl = UILabel(frame: CGRect(x: 15, y: 0, width: view.frame.width - 15, height: 40))
lbl.font = UIFont.systemFont(ofSize: 20)
lbl.text = mobileBrand[section].brandName
view.addSubview(lbl)
return view
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if selectedIndex == indexPath.row && isCollapse == true && selectedSection == indexPath.section{
return 240
}else{
return 60
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if selectedIndex == indexPath.row && selectedSection == indexPath.section{
if self.isCollapse == false
{
self.isCollapse = true
}else{
self.isCollapse = false
}
}else{
self.isCollapse = true
}
self.selectedIndex = indexPath.row
self.selectedSection = indexPath.section
TaskTableView.beginUpdates()
TaskTableView.endUpdates()
}
#objc func PlayBtnClicked(_ sender : UIButton)
{
print(sender.tag)
}
you can use another method like pass tag to button like this
cell.button.tag = (indexpath.section * 1000) + indexpath.row
now on your button action you can get like
let row = sender.tag%1000
let section = sender/1000
you can use closure, please look to my codes :
class YourTableViewCell: UITableViewCell {
var button: UIButton!
var buttonAction: ((UIButton) -> Void)?
#objc func buttonPressed(_ sender : UIButton)) {
self.buttonAction?(sender)
}
}
Implement it to your table view delegate :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell
cell.TaskName.text = mobileBrand[indexPath.section].modelName?[indexPath.row]
cell.TaskPlayButton.tag = indexPath.row
cell.buttonAction = { sender in
// do your action
// in here, you can get indexPath.row and indexPath.section
}
cell.TaskPlayButton.addTarget(self, action: #selector(PlayBtnClicked( _:)), for: UIButton.Event.touchUpInside)
return cell
}
Hope this answer can help you :)
Pass indexPath to cell, when click the button in this cell, you could get the current indexPath
Custom a button hold a property: indexPath. Pass indexPath to the button in the method cellForRowAt. When you click the button, you could use button.indexPath to get what you want.
I just give you quick tip. It just help you on all table view in your project.
You can follow my answer here - https://stackoverflow.com/a/62481414/8135121
Here it's for you.
You can grab it by position of your button.
I explain it to you.
Make a common table view extension on your class. Just use this.
extension UITableView {
func getCellFrom(sender : UIView,completion : #escaping (UITableViewCell,IndexPath)->()){
var superview = sender.superview
while let view = superview, !(view is UITableViewCell) {
superview = view.superview
}
guard let cell = superview as? UITableViewCell else {
return
}
guard let indexPath = self.indexPath(for: cell) else {
return
}
completion(cell,indexPath)
}
}
Set target from cell in your cell for row at IndexPath function.
cell.TaskPlayButton.addTarget(self, action: #selector(PlayBtnClicked( _:)), for: UIButton.Event.touchUpInside)
Call this in PlayBtnClicked action method.
tableView.getCellFrom(sender: sender) { [weak self] (cell, indexPath) in
// Just use indexPath in here
//This closure return your cell and your button's indexPath also
}
I have a tableview with 3 collapsible sections. users can only select rows in section 3 and when they select it goes green. However, when this section is collapsed all the selections are forgotten and when I re-open the section, usually the first row is always green (though it shouldn't be). Sometimes, other sections end up being green too when they shouldn't - not sure what I've got wrong?
// Number of table sections
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
// Set the number of rows
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.expandedSectionHeaderNumber == section) {
// If markscheme, create the markscheme format
if (section == 2)
{
return self.markschemeRows.count
}
else
{
let arrayOfItems = self.sectionItems[section] as! NSArray
return arrayOfItems.count
}
} else {
return 0;
}
}
// Set titles for sections
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if (self.sectionNames.count != 0) {
return self.sectionNames[section] as? String
}
return ""
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44.0;
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat{
return 0;
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
//recast your view as a UITableViewHeaderFooterView
let header: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
header.contentView.backgroundColor = UIColor.darkGray
header.textLabel?.textColor = UIColor.white
if let viewWithTag = self.view.viewWithTag(kHeaderSectionTag + section) {
viewWithTag.removeFromSuperview()
}
let headerFrame = self.view.frame.size
let theImageView = UIImageView(frame: CGRect(x: headerFrame.width - 32, y: 13, width: 18, height: 18));
theImageView.image = UIImage(named: "Chevron-Dn-Wht")
theImageView.tag = kHeaderSectionTag + section
header.addSubview(theImageView)
// make headers touchable
header.tag = section
let headerTapGesture = UITapGestureRecognizer()
headerTapGesture.addTarget(self, action: #selector(CaseViewController.sectionHeaderWasTouched(_:)))
header.addGestureRecognizer(headerTapGesture)
}
// Load the table data
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
let section = self.sectionItems[indexPath.section] as! NSArray
cell.textLabel?.textColor = UIColor.black
cell.selectionStyle = .none
//cell.backgroundColor = .white
// Get the data from different arrays depending on the section
if indexPath.section == 2 {
cell.textData?.text = markschemeRows[indexPath.row]
} else {
cell.textData?.text = section[indexPath.row] as! String
}
return cell
}
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if indexPath.section == 0{
if indexPath.row == 0{
return nil
}
}
else if indexPath.section == 1{
if indexPath.row == 0{
return nil
}
}
return indexPath
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
let cell = tableView.cellForRow(at: indexPath)
cell?.backgroundColor = .green
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath)
if (cell?.backgroundColor == .green)
{
cell?.backgroundColor = .white
}
}
// MARK: - Expand / Collapse Methods
#objc func sectionHeaderWasTouched(_ sender: UITapGestureRecognizer) {
let headerView = sender.view as! UITableViewHeaderFooterView
let section = headerView.tag
let eImageView = headerView.viewWithTag(kHeaderSectionTag + section) as? UIImageView
if (self.expandedSectionHeaderNumber == -1) {
self.expandedSectionHeaderNumber = section
tableViewExpandSection(section, imageView: eImageView!)
} else {
if (self.expandedSectionHeaderNumber == section) {
tableViewCollapeSection(section, imageView: eImageView!)
} else {
let cImageView = self.view.viewWithTag(kHeaderSectionTag + self.expandedSectionHeaderNumber) as? UIImageView
tableViewCollapeSection(self.expandedSectionHeaderNumber, imageView: cImageView!)
tableViewExpandSection(section, imageView: eImageView!)
}
}
}
func tableViewCollapeSection(_ section: Int, imageView: UIImageView) {
let sectionData = self.sectionItems[section] as! NSArray
self.expandedSectionHeaderNumber = -1;
if (sectionData.count == 0) {
return;
} else {
UIView.animate(withDuration: 0.4, animations: {
imageView.transform = CGAffineTransform(rotationAngle: (0.0 * CGFloat(Double.pi)) / 180.0)
})
var indexesPath = [IndexPath]()
// If markscheme, different number needed
if (section == 2)
{
for i in 0 ..< markschemeRows.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
}
else
{
for i in 0 ..< sectionData.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
}
self.tableView!.beginUpdates()
self.tableView!.deleteRows(at: indexesPath, with: UITableView.RowAnimation.fade)
self.tableView!.endUpdates()
}
}
func tableViewExpandSection(_ section: Int, imageView: UIImageView) {
let sectionData = self.sectionItems[section] as! NSArray
if (sectionData.count == 0) {
self.expandedSectionHeaderNumber = -1;
return;
} else {
UIView.animate(withDuration: 0.4, animations: {
imageView.transform = CGAffineTransform(rotationAngle: (180.0 * CGFloat(Double.pi)) / 180.0)
})
var indexesPath = [IndexPath]()
// If markscheme, create the markscheme format
if (section == 2)
{
for i in 0 ..< markschemeRows.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
}
else
{
for i in 0 ..< sectionData.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
}
self.expandedSectionHeaderNumber = section
self.tableView!.beginUpdates()
self.tableView!.insertRows(at: indexesPath, with: UITableView.RowAnimation.fade)
self.tableView!.endUpdates()
}
}
The key thing to understand here is that the Cells are Reused when you say
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
dequeueReusableCell basically reuses a previously loaded UITableViewCell and in your case you changed the background color of the cell to green
To get a better understanding of the concept consider reading some articles like this one on Reusing Cells
Changes in Code
What you should do considering the above in mind
var backgroundColors = [UIColor](repeating: UIColor.white, count: 10)
you have to save the state of the colors in a model (ideally you should make a custom struct)
now in cellForRowAt add this
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
.
.
cell.backgroundColor = backgroundColors[indexPath.row]
// **EDIT**
let cellShouldBeSelected = backgroundColors[indexPath.row] == .green
if cellShouldBeSelected {
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
.
.
return cell
}
And your didSelectRowAt and didDeselectRowAt should update the model
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.backgroundColors[indexPath.row] = .green
tableView.reloadRows(at: [indexPath], with: .none)
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if (self.backgroundColors[indexPath.row] == .green) {
self.backgroundColors[indexPath.row] = .white
tableView.reloadRows(at: [indexPath], with: .none)
}
}
On second thought
Solution 2 (Recommended)
From you comments, i see you only need one selected cell at one time, assuming that keeping an array of backgroundColors is just a bad idea.
declare a int for the selected index
// -1 representing nothing is selected in the beginning
var selectedRow = -1
now your cellForRowAt will look like
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
.
.
if indexPath.section == 2, indexPath.row == self.selectedRow {
cell.backgroundColor = .green
} else {
cell.backgroundColor = .white
}
.
.
return cell
}
And your didSelectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 2 {
self.selectedRow = indexPath.row
tableView.reloadSections([2], with: .automatic)
}
}
And now you can remove didDeselectRowAt completely
I am new in ios I am making a project using table view in which I have expanded the table view cell which has 4 Content view.When the table is loaded only first content view show and when I select the row then all content view expands. But I also want that after expanding the all content view cell when I tap on fourth content view then I want to access the indexPath.row in the tapGESTUREAction method of the fourth view.
this my code of expanding Cell which consists of 4 content view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(YearArr.count)
return YearArr.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! customCell
cell.selectionStyle = .none
cell.lblGrossSal.text = EarnArr[indexPath.row]
cell.lblTotlSal.text = netPayArr[indexPath.row]
cell.lblmonthhName.text = YearArr[indexPath.row]
print(selectedIndex,indexPath.row)
let height = cell.bounds.height
print(height)
return cell;
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! customCell
cell.selectionStyle = .none
if(selectedIndex == indexPath.row) {
return 190;
return self.calculateHeight(selectedIndexPath: indexPath)
} else {
return 50;
}
}
// fourthView
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if(selectedIndex == indexPath.row) {
selectedIndex = -1
} else {
selectedIndex = indexPath.row
}
self.expandTableView.beginUpdates()
//self.expandTableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic )
self.expandTableView.endUpdates()
}
func calculateHeight(selectedIndexPath: IndexPath) -> CGFloat {
let cell = self.expandTableView.cellForRow(at: selectedIndexPath) as! customCell
cell.lblDeductSal.frame = self.cellSummaryLabelFrame(cell: cell, selectedIndexPath: selectedIndexPath)
return 80 + 35 + 21 + 10 + cell.lblDeductSal.frame.size.height + 30
}
func cellSummaryLabelFrame(cell: customCell, selectedIndexPath: IndexPath) -> CGRect {
print(DeductionArr[selectedIndexPath.row])
cell.lblDeductSal.text = DeductionArr[selectedIndexPath.row]
cell.lblDeductSal.numberOfLines = 0
var labelFrame = cell.lblDeductSal.frame
let maxSize = CGSize.init(width: cell.lblDeductSal.frame.size.width, height: CGFloat.greatestFiniteMagnitude)
let requiredSize = cell.lblDeductSal.sizeThatFits(maxSize)
labelFrame.size.height = requiredSize.height
return labelFrame
}
In heightForRowAt indexPath, you are using two return. The first one will execute. The calculated height method can't execute. And there is no need of tableView.dequeueReusableCell. That function only need the height of cell.
Example:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if(selectedIndex == indexPath.row) {
return self.calculateHeight(selectedIndexPath: indexPath)
} else {
return 50;
}
}
And You can also use dynamic cell height, In your viewDidLoad:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44 //Default cell height
And here NO NEED OF heightForRowAt indexPath method. The height will automatically calculate.
SWIFT 3 and Firebase - I'm trying to use the UITable inEditing mode to insert cells into firebase and have a firebase listener that updates my arraty. My insertions to fire base are fine, but I keep getting an index out of range when I try to do the insertion with the new add button i created. Has anyone used Firebase with UITable inEditing mode to insert into a table and update firebase.
This is what I looking for:
enter image description here
The problem maybe be how I wrote the cellForAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("zzz indexPath index path row: \(indexPath.row)")
print("zzz indexPath name \(myPins[indexPath.row].pinName)")
print("ZZZ myPins Count \(myPins.count)")
let cell = tableView.dequeueReusableCell(withIdentifier: "PinCell", for: indexPath)
if indexPath.row == 0 && isEditing {
//this means we are in editing mode an we to add the cell that will be addPlace
//let indexPathOfFirstRow = IndexPath(item: 0, section: 0)
cell.textLabel?.text = "Add Place"
print("add place was called index.row is : \(indexPath.row)")
} else {
//let cell = tableView.dequeueReusableCell(withIdentifier: "PinCell", for: indexPath)
let pin = myPins[indexPath.row]
cell.textLabel?.text = pin.pinName
}
return cell
}
i get this error message: fatal error: Index out of range
Here is the rest of the table set up code:
//When the use press the editing button it will make the table enditable
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
//if the viw is in editing mode then we will set the table to be in enditing mode.
if isEditing {
//This is adding the addtional cell in for add place
tableView.beginUpdates()
let indexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
// self.tableView.insertRows(at: [indexPathOfFirstRow], with: UITableViewRowAnimation.automatic)
tableView.endUpdates()
tableView.setEditing(true, animated: true)
} else {
//when the 'Done' is pressed this will take away the add button
tableView.beginUpdates()
let indexPathOfFirstRow = IndexPath(item: 0, section: 0)
self.tableView.deleteRows(at: [indexPathOfFirstRow], with: UITableViewRowAnimation.automatic)
tableView.endUpdates()
//otherwise the table will not be in editing mode.
tableView.setEditing(false, animated: false)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//STEP 1 for adding a row that will fuction as add place
//If we are in editing mode a 1 will be return and the extra cell will be added
let adjustment = isEditing ? 1 : 0
//add the extra cell if we are in editing mode
return myPins.count + adjustment
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PinCell", for: indexPath)
if indexPath.row == 0 && isEditing {
//this means we are in editing mode an we to add the cell that will be addPlace
//let indexPathOfFirstRow = IndexPath(item: 0, section: 0)
cell.textLabel?.text = "Add Place"
print("add place was called index.row is : \(indexPath.row)")
//addCell.addButton.tag = indexPath.row
//addCell.addButton.addTarget(self, action: "addPlace", for: .touchUpInside)
} else {
// let cell = tableView.dequeueReusableCell(withIdentifier: "PinCell", for: indexPath)
//this is the info I want to dispaly in the cell
let pin = myPins[indexPath.row]
cell.textLabel?.text = pin.pinName
return cell
}
//add the green plus button icon for the extra row added
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
// let indexRow = IndexPath(item: 0, section: 0)
if indexPath.row == 0 {
return .insert
}
return .delete
}
//delete with a with a swipe
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
print("pins count before deleate\(myPins.count)")
if editingStyle == .delete {
let pin = myPins[indexPath.row]
guard let currentUser = FIRAuth.auth()?.currentUser?.uid else {return}
rootRef.child(child.users.rawValue).child(currentUser).child(users.myPins.rawValue).child(plotToEdit!.plotID).child(pin.placeID).removeValue()
}
//When you press on the green plus button as appose to the row.
else if editingStyle == .insert {
let autocompleteController = GMSAutocompleteViewController()
autocompleteController.delegate = self
present(autocompleteController, animated: true, completion: nil)
}
}
//When in ending more I can slect the first row that is add places
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
// let indexPathOfFirstRow = IndexPath(item: 0, section: 0)
if isEditing && (indexPath.row > 0) {
return nil
}
return indexPath
}
I m using swift 2 and UITableViews and when I press a cell a checkmark appear, but I wan't that only one cell can be checked in my tableview so the other checkmarks will disappear from my tableview. I tried different technics without success. I have a CustomCell with just a label.
Here is my code :
import UIKit
class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var tableView: UITableView!
var answersList: [String] = ["One","Two","Three","Four","Five"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return answersList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MyCustomCell", forIndexPath: indexPath) as! MyCustomCell
cell.displayAnswers(answersList[indexPath.row]) // My cell is just a label
return cell
}
// Mark: Table View Delegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Element selected in one of the array list
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
if cell.accessoryType == .Checkmark {
cell.accessoryType = .None
} else {
cell.accessoryType = .Checkmark
}
}
}
}
Assuming you've only section here's what you can do
// checkmarks when tapped
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let section = indexPath.section
let numberOfRows = tableView.numberOfRowsInSection(section)
for row in 0..<numberOfRows {
if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: row, inSection: section)) {
cell.accessoryType = row == indexPath.row ? .Checkmark : .None
}
}
}
Fixed code from #SirH to work with Swift 3
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let section = indexPath.section
let numberOfRows = tableView.numberOfRows(inSection: section)
for row in 0..<numberOfRows {
if let cell = tableView.cellForRow(at:IndexPath(row: row, section: section)) {
cell.accessoryType = row == indexPath.row ? .checkmark : .none
}
}
}