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.
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
}
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)
}
}
I'm using a unclickable tableView to display different information of one object.
For this informations I have different custom cell types one where I placed a map, if my object have locations, one have a list with links, and another a multiple line label for a little description...for example.
I manage this cells with:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell: mapCell = tableView.dequeueReusableCellWithIdentifier("mapCell") as! MapCell
return cell
} else if indexPath.row == 1 {
let cell: textCell = tableView.dequeueReusableCellWithIdentifier("textCell") as! TextCell
return cell
} else if indexPath.row == 2 {
let cell: listCell = tableView.dequeueReusableCellWithIdentifier("listCell") as! ListCell
return cell
}
}
So far so good, everything working fine. My problem is, not every object needs a map, some of them just need some text and a list, other objects need a map and a list, other all of them. I want my tableView to skip some cells if there is a condition.
I know, I can make an symbolic array for changing the number of cells of my tableView, but that deleting just from the end of my tableView, not specific cells.
One of my ideas is to generate a empty cell, maybe with a height of 0 or 1 so that I can do something like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
if mapCellNeeded {
let cell: mapCell = tableView.dequeueReusableCellWithIdentifier("mapCell") as! mapCell
} else {
let cell: emptyCell = tableView.dequeueReusableCellWithIdentifier("emptyCell") as! EmptyCell
}
return cell
} else if indexPath.row == 1 {
...
}...
}
put I don't know if there isn't an efficient way. Hope you guys can help me.
Your solution would work. Another approach (very nice and swifty) would be not to hardcode row numbers, but rather use enum instead:
enum InfoCellType {
case Map
case Text
case Links
}
...
var rows = [InfoCellType]()
...
// when you know what should be there or not
func constructRows() {
if (mapCellNeeded) {
rows.append(InfoCellType.Map)
}
rows.append(InfoCellType.Text)
... etc
}
Then in the table view methods just see what's the type for current indexPath:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellType: InfoCellType = self.rows[indexPath.row]
switch cellType {
case .Map:
let cell: mapCell = tableView.dequeueReusableCellWithIdentifier("mapCell") as! mapCell
return cell
case .Text:
...
case.Links:
...
}
}
This solution also allows to easily change order of rows - just change the order of items in rows array.
I want to implement the "swipe to edit" function for certain rows. If all conditions are fulfilled, the swipe function should be enabled. If not, the row should remain static without any action rowEditAction assigned.
My code looks something like this:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var noAction = UITableViewRowAction()
var logoutAction = UITableViewRowAction(style: .Default, title: "Log Out ") { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
if(indexPath.row == 0){
//do stuff when button pressed
self.tableView.reloadData()
}
else if(indexPath.row == 1){
//do stuff when button pressed
self.tableView.reloadData()
}
}
}
if(indexPath.row == 0 && conditionsFulfilled()){
return [logoutAction]
} else if(indexPath.row == 1 && conditionsFulfilled()){
return [logoutAction]
}
return [noAction]
}
This code does not disable the edit function, it just shows an empty UITableViewRowAction for rows that should not view the logoutAction. How do I get this done properly?
The UITableViewDataSource has a method entitled canEditRowAtIndexPath that according to Apple:
The method permits the data source to exclude individual rows from being treated as editable. Editable rows display the insertion or deletion control in their cells. If this method is not implemented, all rows are assumed to be editable...
So you can do something like this for example:
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// in this case I only allow edit from the third cell hereinafter.
return indexPath.row > 3 ? true : false
}
I hope this help you.