I want to remove the isEditing red icon totally from the table, i also want to reenable the swipe for row actions feature it seems to be overriding.
At the moment i can either have no isEditing command and use swipe to get to my row actions, but cant have my rearrange icons and feature. Or i have isEditing enabled and cant swipe to get to my actions i have to click the massive red button, but i can have my cell rearrange icons...
Is there a way I can have swipe for row actions AND be able to rearrange my cells? WITHOUT the red editing icon overriding everything!
Screenshots of issue: I have to have this red icon to have the rearrange icons, and it disables user swiping for the row actions in pic 2...
Some of the current related code:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
let userExercise = self.fetchedResultsController.self.managedObjectContext
print("EXERCISE TO BE DELETED IS \(userExercise)")
userExercise.delete(self.fetchedResultsController.object(at: indexPath))
do {
try userExercise.save()
print("DELETE COMPLETED")
self.workoutDesignerTable.reloadData()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
let edit = UITableViewRowAction(style: .normal, title: "Edit") { (action, indexPath) in
let cell = tableView.cellForRow(at: indexPath)
self.updateExercise = self.fetchedResultsController.object(at: indexPath)
self.performSegue(withIdentifier: self.segueEditUserExerciseViewController, sender: cell)
}
edit.backgroundColor = UIColor.lightGray
return [delete, edit]
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let UserExercise = fetchedResultsController.self.managedObjectContext
UserExercise.delete(fetchedResultsController.object(at: indexPath))
do {
try UserExercise.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath)-> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
var movableUserExercisesArray = self.fetchedResultsController.fetchedObjects
let movedObject = movableUserExercisesArray?[sourceIndexPath.row]
movableUserExercisesArray?.remove(at: sourceIndexPath.row)
movableUserExercisesArray?.insert(movedObject!, at: destinationIndexPath.row)
print("THIS WAS MOVED FROM \(sourceIndexPath.row) => TO DESINATION \(destinationIndexPath.row)")
// attempting to set index paths - doesnt work as we fetched new?
movedObject?.arrayPosition = Int64(destinationIndexPath.row)
do {
try self.managedObjectContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
EDIT
I have added
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
which now hides the red icon, however i still cant swipe to get to row actions, removing the red button removes any ability to access them when isEditing is on, can the swipe access be restored?
Related
There is a UITableView that uses UITableViewDiffableDataSource. I subclassed UITableViewDiffableDataSource to add canEditRowAt. This correctly shows the swipeable delete action when gesturing the row. However, clicking the delete option does not call tableView(_:commit:forRowAt:). I have read that you have to use tableView(_:trailingSwipeActionsConfigurationForRowAt:indexPath:) because the other function is not supported. I wanted to confirm that was true. If we subclass tableView(_:commit:forRowAt:) as well, we need a clean way to call a function on the original View Controller.
// MyViewController
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete cell
}
}
// Subclass DiffableDataSource used in MyViewController
final class CustomDiffableDatasource: UITableViewDiffableDataSource<MyViewController.Section, MyViewController.Item> {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
guard let item = itemIdentifier(for: indexPath) else {
return false
}
return item.isEditable
}
}
Here is the custom trailingSwipeActionsConfigurationForRowAtfunc looks like for adding a delete swipe. I saw this in another StackOverflow question that referenced a blog post.
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
guard self.dataSource?.tableView(tableView, canEditRowAt: indexPath) == true else {
return nil
}
let delete = UIContextualAction(style: .destructive, title: "Delete") { [weak self] action, view, success in
self?.remove(at: indexPath)
success(true)
}
let swipeActionConfig = UISwipeActionsConfiguration(actions: [delete])
swipeActionConfig.performsFirstActionWithFullSwipe = false
return swipeActionConfig
}
for UITableViews I have added three difference cells
How to Enable delete option for specific cell
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
switch dataSource[indexpath.section].menu {
case "Attachment":
if editingStyle == AttachmentTableViewCell.EditingStyle.delete {
attachmentList.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableView.RowAnimation.automatic)
}
break
default:
break
}
}
In this case it's shows Delete option for other cell too.
How to stop showing the Delete option on swipe to other UITableViewCell.
Implement tableView(_:editingStyleForRowAt:) and return none for the index paths which should not show the delete option.
This worked for me.
Overriding this func from UITableViewController
or implementing it UITableViewDelegate
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
The indexpaths were you want an action return a UISwipeActionsConfiguration else return nil.
like this
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
// return nil on specific rows
guard indexPath.row != 1 else {
return nil
}
let contexualAction = UIContextualAction(style: .normal, title: "Action") { _, _, _ in
// Do Action
}
let swipeAction = UISwipeActionsConfiguration(actions: [contexualAction])
return swipeAction
}
I have a tableview where I am using SwipeCellkit for custom cell deletion. When the delete button is pressed I delete the specified object in realm,
however, I did not reload the tableview but still the tableview row has been deleted. I want to know how it has done (is realm doing implicit tableview reloading?)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
cell.textLabel?.text = categoryArray?[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
// handle action by updating model with deletion
self.updateModel(at: indexPath)
}
// customize the action appearance
deleteAction.image = UIImage(named: "delete-icon")
return [deleteAction]
}
func updateModel(at indexPath: IndexPath) {
if let category = self.categoryArray?[indexPath.row]
{
do{
try self.realm.write {
self.realm.delete(category)
}
}catch{
print("eror deleting object")
}
}
}
This has nothing to do with the Realm.
This is because of the deleteAction that you're returning in editActionsForRowAtIndexPath method.
More precisely, the SwipeActionStyle.destructive is responsible for creating a delete action.
As mentioned in the docs:
The built-in .destructive, and .destructiveAfterFill expansion styles
are configured to automatically perform row deletion when the action
handler is invoked (automatic fulfillment).
Hope this helps
I have a ViewController and added a tableView . It has 2 sections and loads 2 custom cells in each section respectively.But when I swipe to delete some rows in either of the sections, the delete button appears randomly somewhere else on the screen.Tried adjusting constraints of tableView, CommitEditingStyle, canEditRowAtIndexPath.But still the problem persists.
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
if ((indexPath as NSIndexPath).section == 1)
{
let complete = UITableViewRowAction(style: .default, title: "Complete".localized, handler: {[weak self](action, indexPath) -> Void in
if let theSelf = self {
theSelf.completeTask(indexPath)
}
})
complete.backgroundColor = StyleKit.blue10
return [complete]
}
else if ((indexPath as NSIndexPath).section == 2)
{
let reopen = UITableViewRowAction(style: .default, title: "Reopen".localized, handler: {[weak self](action, indexPath) -> Void in
if let theSelf = self {
theSelf.reopenTask(indexPath)
}
})
reopen.backgroundColor = StyleKit.blue10
return [reopen]
}
return []
}
Added Sample Code.
I am trying to change the default button to delete a row in a tableview (when the user swipe left).
Changing the height of the default confirmation delete button
At the same time i would like to add a custom image on the left side of the cell when entering the edit mode...
[Changing the default icon when entering the edit mode to delete2
I've included in my code the:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "\u{267A}\n Delete") { (action, indexPath) in
tableView.isEditing = false
print("delete")
// delete item at indexPath
}
return [delete]
}
is it possible to change the heigh of the confirmation delete button and add a custom image for the left icon?
Thanks!
:)
You need to set UIImage to backgroundColor of UITableViewRowAction.
let someAction = UITableViewRowAction(style: .Default, title: "") { value in
println("button did tapped!")
}
someAction.backgroundColor = UIColor(patternImage: UIImage(named: "myImage")!)