Need a little help from you, I am working on Table View where I have an Array which is received from server. The Array is nothing but Multiple Choice Options. It looks something like this
a. Table
b. Bottle
c. Hat
d. Bucket
e. None of the Above.
What I Want ?
I want to select multiple answers i.e Table , Bottle , Bucket and it is shown by checkbox marked. Which I have managed to do it well. And when last option i.e None of the Above is selected I want to deselect all the above checked mark options and just show the None option checked, even this is working.
Where I am stuck?
When "None of the Above" is in selected mode and I tap on any other option then "None" should be deselected. This is not working , I don't know whats wrong here. Please help. TIA
Here's my didSelect Method
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if selectedString == "None of the above" {
selectedIndex = indexPath.row
self.isNoneSelected = true
for index in tableView.indexPathsForSelectedRows!
{
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
And my None option will always be at last position, so even array.lastobject will work I guess
You are making it too complicated here. All you need is an array of boolean to store the selected states, and reloadData() for the tableView, if you add an UIImageView to represent selected state.
It's not a good idea to call tableView.deselectRow() for every row directly
var selected = Array(repeating: false, count: 5)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) {
//let cell = whatever
cell.checkMark.isHidden = !selected[indexPath.row]
//return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
selected[indexPath.row] = !selected[indexPath.row]
if (indexPath.row == selected.count - 1 ) {//if 'None' is selected
for i in 0..<selected.count-2 {
selected[i] = false
}
} else { //all other rows will deselect the 'None' row
selected[selected.count - 1 ] = false
}
tableView.reloadData()
}
Ok I can't be sure, but it looks like this code handles all selection events, right? If so, there appear to be several problems:
1) selectedIndex is only set if they select the last item. I suspect that is not what you want, but I cannot be sure.
2) same for self.isNoneSelected = true - I suspect you want to use this value in other methods to see if that is the selected item, but you don't seem to have any code to turn it off again.
3) you turn off the selection for all the other items, but don't turn on selection for "none" - but that might have already happened in the event, I don't see the rest of the code there.
So I think you want something like this:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedIndex = indexPath.row
if selectedString == "None of the above" {
self.isNoneSelected = true
for index in tableView.indexPathsForSelectedRows!
{
tableView.deselectRowAtIndexPath(index, animated: true)
}
} else {
self.isNoneSelected = false
//NOTE I AM NOT AT MY MACHINE SO I DON'T KNOW THE EXACT SYNTAX HERE
//THE IDEA IS TO GET THE INDEX PATH OF THE LAST ITEM SO WE CAN TURN IT OFF
tableView.deselectRowAtIndexPath(NSIndexPath.indexPathForRow(mydatasource.count-1, inSection:0), animated: true)
}
}
Related
I have a multiple checkbox in tableview cell and total number of cell 4,i want to select one checkbox at one time and all check box is unselect if i select any one of check box and also one button in table view cell button are also disable of other cell so how i implement this logic.here i implement image check and uncheck logic
func setupData(plansModel: [Plans], mainRowIndex: Int, selctedPlan: Int, isAllUnselected: Bool){
self.plansModel = plansModel
indexMain = mainRowIndex
selectedPlanId = selctedPlan
self.isAllUnselected = isAllUnselected
self.changePlanBtn.isHidden = isAllUnselected
priceTableView.reloadData()
}
i take this variable for data and manage checkbox
I think you want this
First
second
You can do this Way!
Firts make a variable
var selectedIndex: IndexPath = IndexPath(row: 0, section: 0)
Second in tableview didselecte method add this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let previousSelectedIndex = selectedIndex
selectedIndex = indexPath
checkBoxTableView.reloadRows(at: [previousSelectedIndex, selectedIndex], with: .none)
}
third and last add this code in tableview cellForRow Method
if selectedIndex.row == indexPath.row {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
I think your answer is solved.
This Was edited For realod only two row rather than whole tableview (this edit rafrence by paulw11).
Thank you Paulw11 For helping!
How do I make an UITableView which allows sections to either have single or multiple selection?
I have a single UITableView with multiple sections. I want some sections to allow multiple selections and some to only allow a single selection. This is what I currently have:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
// Get the current question
if var question = self.questions[indexPath.section] as? MultipleChoiceQuestion {
// If question allows multiple selection set a checkmark and update question with selected answer
if question.hasMultiValue {
cell?.accessoryType = .checkmark
question.givenAnswer = question.answers[indexPath.row]
} else {
// Question is single selection only. This entire part goes wrong.
if let givenAnswerIsEmpty = question.givenAnswer {
cell?.accessoryType = .none
} else {
self.questions[indexPath.section].givenAnswer = question.answers[indexPath.row]
cell?.accessoryType = .checkmark
}
}
}
}
My objects all have the property hasMultiValue which indicates if a section should allow multiple selections or not. They also have the property givenAnswer which could be seen as a "isSelected" flag. The code above only works for multi selection.
I've been searching around for a solution. There are a few questions like this one but the solution involves using the delegate method didDeselectRowAt. This method won't get called unless I physically deselect the current cell which is not what I want.
What I do want is for example:
If you select row1 and change your mind to row2, you should be able to select row2 which automatically deselects row1.
You didn't try willSelectRowAt?
You can try this code, this is tested on a table view controller
var selectedItemInSection1: Int?
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
// Just return the same index path if the section was not the second one
guard indexPath.section == 1 else { return indexPath }
// Get the previously selected item, and deselect it
if let prev = selectedItemInSection1 {
tableView.deselectRow(at: IndexPath.init(row: prev, section: 1), animated: true)
}
// Save the newly selected item index, to be deselected when other is selected in the same section
selectedItemInSection1 = indexPath.row
// Select the item
return indexPath
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
guard indexPath.section == 1 else { return }
// If it is in the second section, indicate that no item is selected now
selectedItemInSection1 = nil
}
I have Options such as:
None
Had once
Every time
SomeTime
now if none is selected i want other options to be disabled and disable none if any of the options or all are selected.
I have done
func tableView (tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
// first 3 rows in any section should not be selectable
if indexPath.row <= 1 {
return nil
}
return indexPath
}
This lets me to select only others except none. How can i achieve my requirements. Any ideas will be really appericiated.
Thanks.
Take a global variable to keep track of the current selected row and modify the code in your willSelectRowAtIndexPath method as follows :
var selectedRow = -1 //Global Variable
public func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
{
if(indexPath.row>0 && selectedRow == 0) //When "None" option row is selected & user tries to select any other row.
{
return nil
}
else if(indexPath.row == 0 && selectedRow > 0) //When any row other than "None" is selected and user tries to select "None" option row
{
return nil
}
else //When no row is selected or rows other than "None" are selected and user tries to select any row other than "None" row.
{
selectedRow = indexPath.row
return indexPath
}
}
Tested the above code and its working as per your requirements. Do let me know if thats what your were looking for. Cheers.
I've have been sniffing around to find the solution but up until now its fruitless. What I want to do is to determine if a certain cell disappeared from screen.
Here's the code i have been trying:
func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
let indexPathWatchCell = NSIndexPath(forRow: 4, inSection: 0)
if ((tableView.indexPathsForVisibleRows?.contains(indexPathWatchCell)) == nil){
NSLog("it disappeared!!")
}
}
Unfortunately its not working, any ideas?
EDIT:
for clarity, what I want to accomplish is set the size of the cell to CGFLOAT(44) when it disappeared in view
contains method return Boolean value if the object contains other wise return false, so you need to check for that not for nil so change your code like this.
if (tableView.indexPathsForVisibleRows?.contains(indexPathWatchCell)){
NSLog("it not disappeared!!")
}
else {
NSLog("it's disappeared!!")
}
Or if you just want to know for "disappeared" than you can use !(not) with if
if (!tableView.indexPathsForVisibleRows?.contains(indexPathWatchCell)){
NSLog("it disappeared!!")
}
I have a tableView where I want to display different Cells depending on what a variable seguedDisplayMonth is set to. Is this possible and if so can I get any hint on how to do this? I've tried the following but it doesn't seem to work.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Income Cell", forIndexPath: indexPath)
let income = myIncomeArray[indexPath.row]
if seguedDisplayMonth == "All" {
var text = "\(income.money) kr"
cell.textLabel?.text = text
cell.detailTextLabel?.text = income.name
}
return cell
}
I also thought that maybe I need to reload the data after changing the seguedDisplayMonth which gets changed from a different tableView and through a segue.
Call mcTableSwag.reloadData() once seguedDisplayMonth is changed. (Likely call it in the function that actually changes seguedDisplayMonth.
Alternatively you could reload certian cells with some method like reloadVisibleCellsAtIndexPath(...) (Im not sure what it is called exactly, but it should be on the Apple UITableView documentation.
I managed to fix it finally. I will explain how I did it incase anyone runs into the same problem.
I implemented another array myVisibleIncomeArray.
In viewDidLoad() I called a function which does the following:
for inc in myIncomeArray {
if self.monthLabel.text == "All" {
self.myVisibleIncomeArray.append(inc)
totalSum += inc.money
print("Added to myVisible")
}
}
Then I reloadData() and use myVisibleIncomeArray for the other functions.
Not sure if it was the smartest fix, but it's a fix nonetheless.