Swap items in UITableView - has UI issues - ios

I am trying to implement a swap feature inside the uitableview, Currently my table looks like this..
Then i implemented these method
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
swap(&groupList[sourceIndexPath.row], &groupList[destinationIndexPath.row])
reloadData()
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
// delete item at indexPath
print("Delete at index : \(indexPath.row)")
}
delete.backgroundColor = UIColor(red: 210.0/255, green: 30.0/255, blue: 75.0/255, alpha: 1.0)
return [delete]
}
Now it looks like this..
I see two white borders left and right, i want to change that background color of those borders..
also slide to delete is not working anymore (unable to slide right to left, as shown in first image)
can someone help me to fix this

Change cell editing style none to delete
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.delete
}

Use below code. this will work.
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "identuty", for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
// delete item at indexPath
print("Delete at index : \(indexPath.row)")
}
delete.backgroundColor = UIColor(red: 210.0/255, green: 30.0/255, blue: 75.0/255, alpha: 1.0)
return [delete]
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.delete
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

Related

trailingSwipeActionsConfigurationForRowAt not work in stability

I am trying to make swipe-able table view cell for iOS 11 and above and trying to use the trailingSwipeActionsConfigurationForRowAt but it works on iPad and doesn't work on iPhone. It is not called in iPhone.
Surprisingly if I try to swipe the cell more then 10 or 20 times it sometimes works for once.
Here is my controller's table view extension
import UIKit
extension CustomViewController: UITableViewDelegate, UITableViewDataSource {
func initTableView() {
tableView.register(cell: SingleLineListItemViewCell.self)
tableView.delegate = self
tableView.dataSource = self
tableView.estimatedRowHeight = 64
tableView.rowHeight = UITableView.automaticDimension
tableView.backgroundColor = .green
tableView.isEditing = false
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = SingleLineListItemViewModel(title: "coko")
let cell = tableView.dequeueReusableCell(withIdentifier: SingleLineListItemViewCell.reuseIdentifier) as? SingleLineListItemViewCell
cell?.model = model
cell?.isFirst = indexPath.row == 0
cell?.isLast = indexPath.row == 2
return cell!
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return nil
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 64.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
print("didSelectRowAt....")
router?.routeToTransfer()
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
#available(iOS 11.0, *)
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
return nil
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
// Action here
// In case of delete, you can simply do:
if editingStyle == .delete {
//Remove item at relative position from datasource array
//Reload tableview at the respective indexpath
}
}
#available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { _, _, _ in
//YOUR_CODE_HERE
}
deleteAction.backgroundColor = .red
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = false
return configuration
}
}
Any help would be much appreciated.
The only obvious thing wrong with this is that you're not calling the completion handler. According to the API documentation it is necessary to call the completion handler to indicate whether the operation was successful. What it actually does I have no idea...
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { _, _, completionHandler in
//YOUR_CODE_HERE
completionHandler(true)
}
deleteAction.backgroundColor = .red
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = false
return configuration
}
If this doesn't make any difference, do you have any other gesture recognisers that could be conflicting with the swipe action?
you can try this one
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Delete"
}
// this method handles row deletion
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// remove the item from the data model
// delete the table view row
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Not used in our example, but if you were adding a new row, this is where you would do it.
}
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(
style: .normal,
title: "Delete",
handler: { (action, view, completion) in
//do what you want here
completion(true)
})
action.backgroundColor = .red
let configuration = UISwipeActionsConfiguration(actions: [action])
configuration.performsFirstActionWithFullSwipe = false
return configuration
}
Here is are actions defined as well (point 1 and 2);
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "") { _, _, completionHandler in
// 1. remove object from your array
scannedItems.remove(at: indexPath.row)
// 2. reload the table, otherwise you get an index out of bounds crash
self.tableView.reloadData()
completionHandler(true)
}
deleteAction.backgroundColor = .systemOrange
deleteAction.image = UIImage(named: "trash")
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}

UITableView not showing Delete button on clicking minus button(Only on iOS 13)

I have a table view to shows a list of items. I have implemented the default editing style delete. It's been working till iOS 12. But not on iOS 13. It does not show the Delete button when clicking the minus button.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return machineOrders.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MachineOrderCell") as! MachineOrderCell
let machineOrder = machineOrders[indexPath.row]
cell.update(with: machineOrder)
cell.decreaseQuantityButton.isEnabled = canDecreaseQuantity(for: machineOrder)
cell.onDecreaseQuantity = {
self.delegate.view(self, didSelectDecreaseQuantity: machineOrder)
}
cell.onIncreaseQuantity = {
self.delegate.view(self, didSelectIncreaseQuantity: machineOrder)
}
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
navigationItem.rightBarButtonItem = doneBarButton
}
func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {
navigationItem.rightBarButtonItem = !isCartEmpty ? (tableView.isEditing ? doneBarButton : editBarButton) : nil
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let machineOrder = machineOrders[indexPath.row]
if editingStyle == .delete {
self.delegate.view(self, didSelectDelete: machineOrder)
}
}
Press minus button for some seconds, I mean long press, then it will work.

EditActionsForRowAt not working for two tableView on Scrollview in Swift 3

I use two tableView with 5 and 3 cells over scrollview . Trying to use swipeable gesture on both tableView using editActionsForRowAt method of tableView But it just swipe only three cells of first tableView and other cell swipe by trying 5 to 7 times or unswipeable. Help me to get it ,
Thanks in advance
my code
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == table1{
return 5
}
else if tableView == table2{
return 3
}
else{
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == table1{
let cell = meetingTable.dequeueReusableCell(withIdentifier: "myCell") as! meetingCell
cell.cell_name.text = "abc"
cell.cell_copny.text = "08276"
return cell
}
else{
let cell = followTable.dequeueReusableCell(withIdentifier: "myCell") as! FollowUpCell
cell.cell_name.text = "abc"
cell.cell_phone.text = "134135"
return cell
}
}
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 Btn1 = UITableViewRowAction(style: .normal, title: "\u{1F4DE}\n Btn1") { action, index in
//code
}
Btn1.backgroundColor = UIColor.lightGray
let Btn2 = UITableViewRowAction(style: .normal, title: "\u{1F4D3}\n Btn2") { action, index in
//code
}
Btn2.backgroundColor = UIColor.orange
return [Btn2,Btn1]
}

UITableViewCell row action while table is editing

I have a UITableView which I need to both reorder and allow for cells to be deleted by swiping left on a cell to reveal the Delete action. Is it possible to have both at the same time?
For the table I have:
tableView.allowsSelectionDuringEditing = true
tableView.isEditing = true
For the datasource:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
// I do nothing here
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// This is where I rearrange my data source array
}
And for the delegate:
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "Remove") { action, index in
// delete row
}
delete.backgroundColor = UIColor.appRed
return [delete]
}
So what I want to have is:
Reorder control allowing me to move a cell
Swipe left to reveal cell actions
And I need these to be visible and work at the same time. Can this be done?
Swipe to delete is not possible when your UITableView is in editing mode.
If you want to hide the delete button on the left when in editing mode you have to implement the following methods:
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return tableView.isEditing ? .none : .delete
}
I think this is the closest you can get.

Change the text of the cell delete button

i'm trying to change the delete button of a cell.
I have 2 functions :
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let titleBtn = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "Supprimer") { (action , indexPath ) -> Void in
self.isEditing = false
//ackAction.backgroundColor = UIColor.orange
}
return [titleBtn]
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
But, when I run my app, the text of the button is changed but the delete doesn't work (i can't delete data from my array and the row of my tableview). Before to add this functions all worked perfectly.
A detail: in the canEditRowAt function, I tried to return false too...
Thanks by advance
if you want to change the text of the delete button, conform this method in the UITableViewDelegate:
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String?
{
return "Your new title"
}
To delete the item from the array conform this method
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if (editingStyle == UITableViewCellEditingStyle.delete)
{
yourDataSourceArray.remove(at: indexPath.row)
yourTableView.reloadData()
}
}
You can either use default delete action and change its title like this.
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String?
{
return "MyAction"
}
or you can create your own action buttons like this.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction(style: .default, title: "Delete") {action in
//handle delete
}
let editAction = UITableViewRowAction(style: .normal, title: "Edit") {action in
//handle edit
}
return [deleteAction, editAction]
}

Resources