When I click on Edit button in my screen i change my TableView to edit mode and set the edit style as check box by doing this
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.init(rawValue: 3)!
}
now I need programatically pre check some of the entries.
How can i Make some of the cells as checked?
I know in
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
I have to set the edit style which marks it as checked.
I finally figured it out.
Setting the Checkbox in an table view is equivalent to selecting the cell.
so all you need to do is mark the sell as selected, nothing to do with the Edit style
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
let item = self.items[indexPath.row]
cell.setup(item: item)
cell.setSelected(true, animated: true) // Provided your cell is already in check box edit mode, then this makes it CHECK ON
return cell
}
By the way. I saw an explanation in similar question here (on SO) that you should not use this:
return UITableViewCellEditingStyle.init(rawValue: 3)!
Because it's not public API and if Apple changes this value, application will stop working properly. The same behaviour can be reached simply by enabling Multiple selection during editing:
You can check it easily by setting breakpoint on your overridden method
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.init(rawValue: 3)!
}
And enable editing during running the app with Multiple selection during editing and without it. You will see that if Multiple selection during editing is enabled, this method will not be called at all.
Related
I am currently working on a solution where I need to have a UITableView by default in reorder mode without having a delete button but could enable the delete button when necessary. I am just curious if this is even achievable in iOS? If so what should be my approach for this?
In my opinion your table view should always be in edit mode.
To make the reorder controls appear you should implement UITableViewDataSource methods
tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
and
tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
If you don't want the delete button to be displayed you can do that by implementing
tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle
and return .none by default or .delete when you want to have the button displayed.
I trying to port my iOS app to macOS using Catalyst, but no matter what the UITableViewCellSelectionStyle.gray style visually show the .blue highlight, while the .style value still prints .gray.
I tried to force reset it in the following functions but with no luck.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
No matter what, it goes back .blue from .gray. If its .none, it stays .none.
Possible workaround was to set a background color manually, which feels like not right.
The blue color was from the focused state, so you will need to override the canBecomeFocused property in your UITableViewCell subclass
override var canBecomeFocused: Bool {
return false
}
The default way of setting the selection style on Mac Catalyst did not work for me:
cell.selectionStyle = .gray
On the Mac Catalyst app the selection showed first gray then on the next click blue. To work around it I applied #Laszlo's solution. However you don't need a custom UITableViewCell. You can create a custom background view and set the .selectedBackgroundView property of the UITableViewCell instance to a custom background view.
let customSelectionBackgroundView = UIView()
customSelectionBackgroundView.backgroundColor = UIColor.red
cell.selectedBackgroundView = customSelectionBackgroundView
As others have stated, the blue highlight comes from the focused state. To disable it you can implement the table view function canFocusRowAt and just return false, like this:
func tableView(_ tableView: UITableView, canFocusRowAt indexPath: IndexPath) -> Bool {
return false
}
I am trying to achieve to make my TableView only accept one checkbox per cell.
I have used this solution to save User Defaults for the checkmarks which works fine but it allow multiple selections.
I have tried so many solutions on Stack overflow but since this is formatted a little different I was unable to use those solutions.
Things I have tried which did not work:
Tried setting the accessory type to none at the didDeselectRowAt
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
Tried setting the table view to not allow multiple selections on the viewDidNotLoad
override func viewDidLoad()
{
tableViewName.allowsMultipleSelection = false
}
Based the solution I linked, how would I go to only allow a single selection?
In the solution you have linked there is this code in the 'didSelect' function
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if selectedRows.contains(indexPath.row) {
self.selectedRows = selectedRows.filter{$0 != indexPath.row}
}else{
self.selectedRows.append(indexPath.row)
}
UserDefaults.standard.set(selectedRows, forKey: "selectedRows")
}
If you only want a single checkbox to be selected then you only want a single entity saved in your selectedRows object. Change the above code to:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
self.selectedRows = [indexPath.row]
UserDefaults.standard.set(selectedRows, forKey: "selectedRows")
}
Then every time a checkbox is selected it will clear out all the other selected checkboxes and select only the checkbox you just clicked.
I have a UITableViewCell where I have implemented leadingSwipeActionsConfigurationForRowAt indexPath to allow users to drag right on cells to add them to their favorites. However, in doing so the option for dragging left to delete also appeared. I don't want these cells to be able to be deleted. Is there a way to implement swipe actions without the delete action appearing?
Try this
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return false
}
Edit
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let swipeAction = UISwipeActionsConfiguration(actions: [])
swipeAction.performsFirstActionWithFullSwipe = false // This is the line which disables full swipe
return swipeAction
}
I am trying to learn Swift, but there is a problem in my project that drives me nuts.
I have a working list of data in a ViewController fed by parse.com. I managed to implement a swipe-feature that reveals buttons for both deleting and editing. That is working fine. Now I want the user to be able to reorder the cells. So I successfully implemented a button to put the table into editing-mode. My 2 problems with that are:
When I enter edit-mode I just want to be able to reorder the cells since editing and deleting is done via swipe (via "tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath)". How can I achive that the user doesn't see the 2 buttons for deleting and editing when in editing-mode and touching the delete-circle that is provided automatically?
Is it possible to remove the delete-circle altogether? Using "UITableViewCellEditingStyle.None" also disables the swipe-functionality.
Thanks in advance!
To avoid the round red delete button that appears when you put set UITableView isEditing to true at the left and does nothing when you click it, the minimum that worked for me was this (Swift 4, iOS 11)
// Avoid the round red delete button on the left of the cell:
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
I also have these functions, which probably interact:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return savedTempTable.isEditing
}
// Including this function in the delegate enable left-swipe deleting
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete {
savedConversions.remove(at: indexPath.row)
}
}
// Including this function enables reordering
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath,to destinationIndexPath: IndexPath)
{
let elem = savedConversions.remove(at: sourceIndexPath.row)
savedConversions.insert(elem, at: destinationIndexPath.row)
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
Although people can delete a row through swipe the delete-button in editing mode should not be removed. People may not know about the swipe gesture and by removing the delete button (which they already expect in editing mode) the app becomes more difficult to use.
If you really want to remove the delete button then you have to implement the delegate method tableView(_:editingStyleForRowAtIndexPath:). There you can return .None while the screen is in editing mode and .Delete while the screen is not.
To enable reordering you have to implement the data source methods tableView(_:canMoveRowAtIndexPath:) and tableView(_:moveRowAtIndexPath:toIndexPath:).
You follow this way to remove the delete Icon while editing:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellAccessoryNone;
}