I have a UIViewController with tableView and custom cell. I want to add swipe delete button to cell. When i used UITableViewController and define editActionsForRowAtIndexPath swipe button works well. But now it doesn't appear. Swipe action is working, but button is not appear. What i'm doing wrong ?
class CartViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView:UITableView!
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
...
return items_count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete",handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
...
})
return [deleteAction]
}
}
Related
I have a UITableView inside a UIViewController. I am trying to make it so when the user click the BarButtonItem in the NavigationBar, that the tableview goes into editing mode, and thus the user can drag and reorder the cells.
However, what happens is that I simply press the editing button, and nothing happens.
This is what I have tried:
For the array declaration:
var tester = ["1", "2", "3"]
For the button declaration:
#IBAction func editButtonPressed(sender: AnyObject) {
self.editing = !self.editing
}
For the various tableview functions:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return tester.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("editCell", forIndexPath: indexPath) as! EditTableViewCell
cell.nameHolder?.text = tester[indexPath.row]
// Configure the cell...
return cell
}
func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
var itemToMove = tester[fromIndexPath.row]
tester.removeAtIndex(fromIndexPath.row)
tester.insert(itemToMove, atIndex: toIndexPath.row)
}
func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the item to be re-orderable.
return true
}
What could be causing this bug?
Swift 4.1
In → func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
Add this line to configure the cell:
cell.isEditing = self.tableView(tableView, canMoveRowAt: indexPath)
Ran Hassid has the most correct answer to this in his comment.
This will solve the problem:
#IBOutlet weak var tableView: UITableView!
#IBAction func editButtonPressed(sender: AnyObject) {
tableView.setEditing(!tableView.isEditing, animated: true)
}
I am using the method
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
{
let delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
//Do something
})
delete.backgroundColor = UIColor.redColor()
let more = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
//Do something
})
more.backgroundColor = UIColor.blueColor()
return [delete, more]
}
I also included
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
// you need to implement this method too or you can't swipe to display the actions
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// the cells you would like the actions to appear needs to be editable
return true
}
and when I swipe right or left the buttons I created are not showing up. I tried putting override on the editactionforrowatindexpath but then i get an error saying method does not override any method from its super class
There is nothing wrong in your implementation. The function is not getting called is because the delegate and datasource methods are not called properly.
You can connect the delegate and datasource methods by programatically or via storyboard.
When you are implement the tableview programatically You need to add UITableViewDataSource, UITableViewDelegate in class declaration and connect the delegates using this code.
yourTableView.datasource = self
yourTableView.delegate = self
If you are implement tableview through storyboard you just need to connect the delegate and data source method by dragging
I tried to customize my delete button in UITableView. I used a function but it didn't work because Xcode found an error. By the way I'm using custom cells in UITableView.
This is my code:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
let deleteButton = UITableViewRowAction(style: .Default, title: "Delete", handler: { (action, indexPath) in
self.myTableView.dataSource?.tableView?(
self.myTableView,
commitEditingStyle: .Delete,
forRowAtIndexPath: indexPath
)
return
})
deleteButton.backgroundColor = UIColor.blackColor()
return [deleteButton]
}
}
And in this line is error:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
the erros is: Objective-C method 'tableView:editActionsForRowAtIndexPath:' provided by method 'tableView(:editActionsForRowAtIndexPath:)' conflicts with optional requirement method 'tableView(:editActionsForRowAtIndexPath:)' in protocol 'UITableViewDelegate'
So I want to change the text and background color. If there is any other method, like using icon and not text please show me, thanks.
The error is indicating that the function you defined with the same method signature as the one defined in UITableViewDelegate has different types that are not compatible. Specifically your return type needs to be [UITableViewRowAction]? instead of [AnyObject]?
Change:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
To:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
Your main problem is that the UITableViewDelegate method is
optional public func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
and not
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?
I hope this helps you
In my iOS app I have a UITableViewController whose rows contain data and data picker. I want to change te function of the buttons Edit and Done. I would like the Edit button to allow the user to write/insert data (instead of deleting rows), while I would like the Done button to save to save the data (and not just exiting the edit mode). I've added to my code the following:
// The following two functions remove the red minus sign
override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.None
}
override func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
in order to avoid appearing the circle red minus, but how can I override the functions according to Edit or Done value of the button? I heard about delegates but I'm new to iOS and I don't know what they are...if someone can explain me I would be grateful.
Please try this code block :-)
import UIKit
// You can initialise an instance of this class manually or configure it on storyboard
class TableViewController: UITableViewController {
// MARK:- This part is for demo purpose
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.backgroundColor = UIColor.yellowColor()
cell.textLabel?.text = "\(indexPath.row)"
return cell
}
// MARK:- From here is the main part to answer your question
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let editAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Edit") { (action, indexPath) -> Void in
print("Write/Insert data here")
}
let doneAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Done") { (action, indexPath) -> Void in
print("Save data here")
}
doneAction.backgroundColor = UIColor.blueColor()
return [doneAction, editAction]
}
}
You will see the result like this
I have UIviewController which contains a UITableView , it's a very simple code , I just want to swipe one cell and show more and delete and handle these two events , this is my very simple class
class ViewController: UIViewController , UITableViewDataSource , UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
let deleteClosure = { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
println("Delete closure called")
}
let moreClosure = { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
println("More closure called")
}
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = "\(indexPath.row)"
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?
{
var moreAction = UITableViewRowAction(style: .Default , title: "More") { (action : UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
println("more")
}
moreAction.backgroundColor = UIColor.lightGrayColor()
var deleteAction = UITableViewRowAction(style: .Default, title: "Delete") { (action: UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
println("delete")
}
return [moreAction , deleteAction]
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
if (editingStyle == .Delete)
{
println("delete1")
}
if(editingStyle == .Insert)
{
println("insert")
}
}
the editActionsForRowAtIndexPath function get called but none of the RowActions shows up !
what's the problem ? ,
you need to do something in the handlers of your custom buttons.
For example, with a custom delete button (and just to change its label and background color), you would do somehting like:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
let button = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: NSLocalizedString("TitleOfDeleteButton", comment: "Delete"), handler: { (rowAction, indexPath) -> Void in
self.tableView(self.tableView!, commitEditingStyle: UITableViewCellEditingStyle.Delete, forRowAtIndexPath: indexPath)
})
button.backgroundColor = UIColor.lightGrayColor()
return [button]
}
Also, don't forget that this method of the UITableViewDelegate protocol came only with iOS8