How to customize delete button in UITableView - ios

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

Related

Issue with tableview method func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?

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

Is there a way of implementing editActionsForRowAtIndexPath only for a specific UITableViewCell in Swift?

I'm implementing a UITableViewController in my app and I want to add a possibility of sliding/swiping a cell on my tableview, exactly like in this answer: Swipe-able Table View Cell in iOS 9 but with a difference that it works only for one specific cell, not all of them. So far I have:
class MyTableViewController: UITableViewController {
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: (UITableView!), commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: (NSIndexPath!)) {
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
var deleteAction = UITableViewRowAction(style: .Default, title: "Hello There!") {action in
print("some action!!")
}
return [deleteAction]
}
}
and it adds the swiping for all cells and I want to add it only to the 3rd one on my list (cells are not generated dynamically). Is there a way of doing that?
You can check the indexPath of the cell which is given as parameter and return the appropriate response based on that. Furthermore, you could also check the type of your cell using func cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell? if you have different cells or so.
Index path is a class. You can get the index of the current row from the indexPath using indexPath.row.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
if ((indexPath.row % 3) == 0) {
return true
} else {
return false
}
}

Swipe button doesn't show at cell

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]
}
}

Swift: how to change Edit/Done buttons behaviour/function

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

Type "someViewContoller" does not conform to protocol "UITablViewDataSource"

I am really new to the whole Swift thing and also programming in general. I have researched everywhere but couldn't find an answer for the error that I got. Please help me :)
import Foundation
import UIKit
class TümÜrünlerViewController : UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tümÜrünlerTableView: UITableView!
#IBAction func cancelTapped(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
var ürünler = ["Havalı", "Daha Havalı", "Eheheh"]
var ürün = "Balık"
func TableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell()
cell.textLabel!.text = self.ürünler[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.ürün = self.ürünler[indexPath.row]
self.performSegueWithIdentifier("başlıklardanÖzeleSegue", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tümÜrünlerTableView.dataSource = self
self.tümÜrünlerTableView.delegate = self
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var detailViewController = segue.destinationViewController as BaşlıklarViewController
detailViewController.ürün = self.ürün
if self.ürün == "Havalı" {
detailViewController.label = "anan"
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->Int {
return self.ürünler.count
}
}
Here is my code but I am getting the error when I try to insert UITableViewDataSource. I tried everything that the forums said but it docent seem to work for me :(
My guess:
Let us look at this method. T needs to be decapitalized. tableView not TableView
func TableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell()
cell.textLabel!.text = self.ürünler[indexPath.row]
return cell
}
It's a very simple mistake - the UITableViewDataSource requires that 2 methods are implemented:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
but you've just made a typo in the 2nd one:
func TableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
^
the method name should start in lowercase: tableView(...)
You have a capital T on your cellForRowAtIndexPath function. It should read:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell()
cell.textLabel!.text = self.ürünler[indexPath.row]
return cell
}
Reason behind error is that, you are not calling datasource required method in correct order. Correct order of calling is :
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
Always, make sure you call numberOfRowsInSection before cellForRowAtIndexPath.

Resources