I have implemented a leading swipe action ('Delete') on my tableView which for a reason I can't figure out is also appearing as a trailing swipe action. See code below:
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) ->
UISwipeActionsConfiguration? {
let delete1 = deleteAction(at: indexPath)
return UISwipeActionsConfiguration(actions: [delete1])
}
func deleteAction(at indexPath: IndexPath) -> UIContextualAction {
let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, completion) in
self.delete(at: indexPath)
}
return action
}
I used to have a trailing swipe action, but I deleted this function out completely. When I change 'leadingSwipeActionsConfigurationForRowAt' to 'trailingSwipeActions...' then only the trailing swipe action appears. Be grateful if anyone could tell me what I've missed. Thanks.
Use this code to prevent trailingSwipeAction()
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle
{
return .none
}
or
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
return UISwipeActionsConfiguration(actions: [])
}
Because that is the default behaviour, when swipes are enabled. You can do something like this to disable swipes on the trailing side, if you want to implement the destructive delete action on the left only.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
return UISwipeActionsConfiguration(actions: [])
}
By passing an empty set of actions, the trailing swipe will disappear due to having 0 set of possible actions.
Related
How to ignore the right to left swipe or the Trailing swipe, does anyone know how to accomplish this?
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let swipeAction = UISwipeActionsConfiguration(actions: [])
return swipeAction
}
If a row is deleted, tableView shows black area below cells, while tableView has white background color as with the cell view.
Look at this:
https://www.dropbox.com/s/55ssb73t0ngr9yj/screenshot.png?dl=0
After deleting a row (it can be any one of them, not necessarily the last one), suddenly, black area shows up, though I didn't change any constraint or height of the tableView. Also, behind tableView, there is nothing in this area other than the 'self.view' whose background is also white, and in front of table view, no view is positioned. (one view is there, but it is the size of the screen, so it cannot be black only for this area.)
extension ApptDetailViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return appt.places.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ApptDetailCell", for: indexPath) as! ApptDetailCell
cell.placeNumLabel.text = "Place \(indexPath.row + 1)"
cell.placeNameLabel.text = appt.places[indexPath.row]
return cell
}
}
extension ApptDetailViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let moveString = appt.places.remove(at: sourceIndexPath.row)
let moveBool = appt.reachedPlaces.remove(at: sourceIndexPath.row)
appt.places.insert(moveString, at: destinationIndexPath.row)
appt.reachedPlaces.insert(moveBool, at: destinationIndexPath.row)
print("appt.places: \(appt.places)")
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// deletion occurred.
appt.places.remove(at: indexPath.row)
appt.reachedPlaces.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .right)
}
}
}
As per our comment discussion —You can debug your UI using the view heirarchy debugger. This helps pinpoint anomalies in your views.
Or try to change the tableview background color.
I have custom cells of UITableView which consist of UIImage and textLabel. When I select the editing mod, the textLabel shows the following image;
I want to move it to left. I tried all of things to do but it didn't work.
Please let me know.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allRows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "editCell", for: indexPath) as! CustomTableView
cell.textLabel?.text = self.allRows[indexPath.row].bname
cell.textLabel?.textAlignment = .left
let image:UIImage = UIImage(named: "group")!
cell.imageView!.image = image
return cell
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle{
return .delete
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){
if editingStyle == .delete{
self.allRows.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)
}
}
#objc func leftEditButtonPressed(_ sender: UIButton) {
self.tableView!.isEditing = true
self.tableView?.setEditing(true, animated: true)
}
look at this, I hope it helps you:
swipe left/right in tableViewCell
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let closeAction = UIContextualAction(style: .normal, title: "Close", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
print("OK, marked as Closed")
success(true)
})
closeAction.image = UIImage(named: "tick")
closeAction.backgroundColor = .purple
return UISwipeActionsConfiguration(actions: [closeAction])
}
Try using the following code:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataArr.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80.0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableCell") as? TestTableCell else {
return UITableViewCell()
}
cell.customImageView.image = #imageLiteral(resourceName: "ic_audio")
cell.customTitleLabel.text = self.dataArr[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.delete
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
print("delete at \(indexPath.row)")
}
}
Here is the output for this code:
Note: You can change the editing action in editingStyleForRowAt method and for performing the action you need to write the logic in commit editingStyle method.
Hope this help you!
I suggest you to create new label in that UITableViewCell and connect that label to custom UITableViewCell class ! then you are free to do anything !
Swift 4 :
Create a new class which is subclass of UITableViewCell !
In your storyboard in right menu which called Utilities in toolbar of Utilities go to the Identity inspector defince your cell class to your new UITableViewCell class
Drag and drop UILabel from Object library into your cell
now using drag and drop connect that label to your UITableViewCell class then create an Outlet
Perfect !
now use myLabel instead of textLabel ;)
dont forget to cast your cell as! YourCustomCellClass
Good Luck ;)
I've built a simple toDoList app with Swift 3. Now I want to be able to delete my items from a TableView by swiping from right to left. This code is what I've found. But nothing happens when I swipe to the left.
CODE:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return toDoList.count
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.textLabel?.text = toDoList[indexPath.row]
return cell
}
//
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
toDoList.remove(at: indexPath.row)
UserDefaults.standard.set(toDoList, forKey: "toDoList")
tableView.reloadData()
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .delete
}
This still does not work. Nothing happens when I swipe to the left. The to do List itself is working. I can add items to the table but I just can't remove them.
Thanks :)
Did you implement tableView:canEditRowAtIndexPath: method?
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
EDIT:
Thanks to #rmaddy for mentioning that the default value of tableView:canEditRowAtIndexPath: is true, implementing it doesn't solve the problem.
I'm not pretty sure of what are you trying to do from your code snippet, so make sure that you are implementing the following methods (UITableViewDelegate):
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
toDoList.remove(at: indexPath.row)
UserDefaults.standard.set(toDoList, forKey: "toDoList")
tableView.reloadData()
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .delete
}
You can also keep the implementation of tableView:canEditRowAtIndexPath: method:
Asks the data source to verify that the given row is editable.
So, -for example- if you want to let the first row is not editable, i.e user cannot swipe and delete the first row, you should do somthing like:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
if indexPath.row == 0 {
return false
}
return true
}
Make sure that the UITableViewDataSource and UITableViewDelegate are connected with the ViewController.
I am trying to add a second swipe button to my table view rows, but editActionsForRowAtIndexPath is not being called when I swipe a row. This is despite my class declaring both
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
and
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
Both of these are called when I swipe because I also have a regular delete button.
My editActionsForRowAtIndexPath function is written as follows:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewRowAction? {
print("triggered!")
let more = UITableViewRowAction(style: .default, title: "More") { action, index in
print("more button tapped")
}
more.backgroundColor = UIColor.blue
return more
}
Thanks in advance!
You are not using the updated Swift 3 API for this particular method. The delegate method should be written as:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
print("triggered!")
let more = UITableViewRowAction(style: .default, title: "More") { action, index in
print("more button tapped")
}
more.backgroundColor = UIColor.blue
return [more]
}