I am a total newbie to Swift and XCode. I am in the process of creating a to do list application. I am attempting to mark a task as complete when a user swipes the cell in the table and clicks a "complete" button, but I am having difficulty targeting a specific table cell in order to do this. I found this example: UILabel with text struck through (see comment by MicroR), which helped me actually figure out how to do a strikethrough on a given piece of text, and I have this basic idea of strikethrough working if I just add it in when I create my table cells in my cellForRowAtIndexPath function. The issue is that I would like to only mark a task as complete when a user clicks the complete button after swiping on that specific cell in the table. I need some help with the code for targeting a cell after the user pushes the "complete" button (this function is the last one in the code below, but I included the rest of the code in this function for clarity). Thank you!
Here is the code that allows a strikethrough to happen when I put it in my cellForRowatIndexPath function
let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: message)
attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: NSMakeRange(0, attributeString.length))
Here is my code:
// I pull in fake data right now from another function - sentData1 contains my task item.
var sentData1:String!
var sentData2:String!
var sentData3:String!
var sentData4:String!
var sentData5:String!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
self.navigationItem.title = sentData5
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.section [section]
}
override func numberOfSections(in tableView: UITableView) -> Int {
return self.section.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Task", for: indexPath)
cell.selectionStyle = .none
switch (indexPath.section)
{
case 0:
cell.textLabel?.text = sentData1
case 1:
cell.textLabel?.text = sentData2
case 2:
cell.textLabel?.text = sentData3
case 3:
cell.textLabel?.text = sentData4
default:
cell.textLabel?.text = "Other"
}
return cell
}
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .normal, title: "Delete") { action, index in
print("delete button tapped")
}
delete.backgroundColor = UIColor(red: 27/255, green: 124/255, blue: 150/255, alpha: 1.0)
let edit = UITableViewRowAction(style: .normal, title: "Edit") { action, index in
print("edit button tapped")
}
edit.backgroundColor = UIColor(red: 130/255, green: 208/255, blue: 216/255, alpha: 1.0)
let markComplete = UITableViewRowAction(style: .normal, title: "Complete") { action, index in
// this is where I want to target the cell!
print("complete button tapped")
}
markComplete.backgroundColor = UIColor(red: 0/255, green: 66/255, blue: 89/255, alpha: 1.0)
return [edit, delete, markComplete]
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
{
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
:)
I am a total newbie to Swift and XCode too..
My english is no good too :)
but if i understood you.
I think that the answer to your question is..:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
let delete = UITableViewRowAction(style: .normal, title: "Delete") { action, index in
self.Apertou_Botao(pIndice: indexPath.row, pTexto: "Apertou Deletar")
}
delete.backgroundColor = UIColor(red: 27/255, green: 124/255, blue: 150/255, alpha: 1.0)
return [delete]
}
func Apertou_Botao(pIndice : Int , pTexto : String)
{
print("\(pTexto) indice Clicado..: \(pIndice)");
}
}
Related
I built an app using mvvm architecture. I don't know why
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
it's not getting called on my view controller (basically swipe doesn't work, it can work like 1/20). If I build the tableview (basic one) with its methods to another view controller it works well. I tried to build one more time from scratch my view controller, but also it doesn't affect the result, so the problem is definitely in the functionality of the controller.
My code where swipe works well (I did that only to check if that works in my app:)
class tbViewController: UIViewController {
#IBOutlet weak var tableview: UITableView!
private var data = ["1","2","3","4"]
override func viewDidLoad() {
super.viewDidLoad()
tableview.delegate = self
tableview.dataSource = self
}
}
extension tbViewController: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = self.data[indexPath.row]
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
self.data.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
}
And my original view controller where swipe doesn't work, I also swapped original tableview with above one, only to verify if the problem is from tableview... I can't get it :C. (Please check first tableview methods) :
class ExpensesViewController: UIViewController, ChartViewDelegate {
#IBOutlet private weak var thisWeek: UIButton!
#IBOutlet private weak var thisMonth: UIButton!
#IBOutlet private weak var thisYear: UIButton!
#IBOutlet private weak var totalExpensedAmount: UILabel!
#IBOutlet private weak var pieChart: PieChartView!
#IBOutlet private weak var tableView: UITableView!
private var menu: SideMenuNavigationController?
private var tableViewActions = [Action]()
private var expensesViewModel = ExpensesViewModel()
private var data = ["1","2","3","4"]
override func viewDidLoad() {
super.viewDidLoad()
initSideBar()
customizeButtons()
customizePieChart()
self.tableView.delegate = self
self.tableView.dataSource = self
}
#IBAction func didTapMenu(){
present(self.menu!, animated: true)
}
#IBAction func onClickThisWeek(_ sender: UIButton) {
setGrayBackgroundAndBlackTitleColor(for: self.thisMonth, and: self.thisYear)
sender.backgroundColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
sender.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: UIControl.State.normal)
}
#IBAction func onClickThisMonth(_ sender: UIButton) {
setGrayBackgroundAndBlackTitleColor(for: self.thisWeek, and: self.thisYear)
sender.backgroundColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
sender.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: UIControl.State.normal)
}
#IBAction func onClickThisYear(_ sender: UIButton) {
setGrayBackgroundAndBlackTitleColor(for: self.thisWeek, and: self.thisMonth)
sender.backgroundColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
sender.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: UIControl.State.normal)
}
private func setGrayBackgroundAndBlackTitleColor(for button1: UIButton, and button2: UIButton){
button1.backgroundColor = #colorLiteral(red: 0.921431005, green: 0.9214526415, blue: 0.9214410186, alpha: 1)
button2.backgroundColor = #colorLiteral(red: 0.921431005, green: 0.9214526415, blue: 0.9214410186, alpha: 1)
button1.setTitleColor(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), for: UIControl.State.normal)
button2.setTitleColor(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), for: UIControl.State.normal)
}
private func initSideBar(){
self.menu = SideMenuNavigationController(rootViewController: MenuListController())
self.menu?.leftSide = true
self.menu?.setNavigationBarHidden(true, animated: false)
SideMenuManager.default.leftMenuNavigationController = self.menu
SideMenuManager.default.addPanGestureToPresent(toView: self.view)
}
private func customizeButtons(){
self.thisWeek.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: UIControl.State.normal)
self.thisWeek.backgroundColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
self.thisWeek.layer.borderColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
self.thisMonth.layer.borderColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
self.thisYear.layer.borderColor = #colorLiteral(red: 0.05509413034, green: 0.7074701786, blue: 0.4755263329, alpha: 1)
}
private func customizePieChart(){
self.pieChart.delegate = self
self.pieChart.noDataText = "You don't have any income, to display quarters income."
self.pieChart.legend.enabled = false
let pieChartAttribute = [ NSAttributedString.Key.font: UIFont(name: "Arial", size: 16.0)!, NSAttributedString.Key.foregroundColor: UIColor.init(displayP3Red: 0.462, green: 0.838, blue: 1.000, alpha: 1) ]
let pieChartAttrString = NSAttributedString(string: "Quarterly Revenue", attributes: pieChartAttribute)
self.pieChart.centerAttributedText = pieChartAttrString
}
}
extension ExpensesViewController: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = self.data[indexPath.row]
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
self.data.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
}
How original screen should be:
How my screen is now, I commended basically all functionality to not confuse you, where my all business logic is, that's why nothing is displayed, it's just some UI changing, view model doesn't interact with controller(as you see in my code above):
If you have encountered such errors, please help me. Thanks a lot.
I would try using this: https://developer.apple.com/documentation/uikit/uitableviewdelegate/2902367-tableview
There’s also a similar function for leading swipes.
"I don't know why
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) it's not getting called on my view controller".
The reason your method it is not getting called is that you forgot to add at the declaration of your view controller that it should be the UITableViewDelegate.
Note: using beginUpdates method is pointless to delete/remove a single row. Btw when doing multiple insertions/deletions better to use performBatchUpdastes. Last but not least, it is Swift naming convention to name your classes starting with an uppercase letter.
I have a dynamic prototype table view. This table view displays an array of structs. Each struct is being represented by two cells, to be exact by DateCell and timelineCell.
In this case the date cell is the header and added with: func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {.
I want the DateCell (HeaderCell) on the top of the table view (first index of array) to have a different look. I've figured out how to change the background etc. (see viewForHeaderInSection) of this header, but how can I change the height of this exact cell?
extension TimelineViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return addDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let rowData = addDataArray[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "TimelineCell") as! TimelineCell
cell.setDrivenKm(drivenKm: rowData.driven)
cell.setConsumedL(consumedL: rowData.consumedL)
cell.setPricePerLiter(pricePerLiter: rowData.pricePerLiter)
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let rowData = addDataArray[section]
guard let last = addDataArray.first else { return nil }
let color: UIColor!
let headerCell = tableView.dequeueReusableCell(withIdentifier: "DateCell") as! DateCell
if rowData.date == last.date {
color = UIColor.white
headerCell.backgroundColor = UIColor(red: 0/255, green: 22/255, blue: 60/255, alpha: 1)
} else {
color = UIColor(red: 0/255, green: 22/255, blue: 60/255, alpha: 1)
}
headerCell.setDate(date: rowData.date, color: color)
return headerCell
}
}
You need to implement ( for static )
func tableView(_ tableView: UITableView,
heightForHeaderInSection section: Int) -> CGFloat {
return 100.0
}
for dynamic
self.tableView.estimatedSectionHeaderHeight = 100.0
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
and make sure your constraints are hooked propely inside the cell , top , leading , trailing and bottom
Although the previous answer is correct, if you have only two items in the section (the header and the cell) and in your implementation both items are subclasses of UITableViewCell, then you can use both of them inside the cellForRowAt method. Just increase the number in numberOfRowsInSection to 2 and switch over indexPath.row.
extension TimelineViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func numberOfSections(in tableView: UITableView) -> Int {
return addDataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
let rowData = addDataArray[section]
guard let last = addDataArray.first else { return UITableViewCell() }
let color: UIColor!
let headerCell = tableView.dequeueReusableCell(withIdentifier: "DateCell", for: indexPath) as! DateCell
if rowData.date == last.date {
color = UIColor.white
headerCell.backgroundColor = UIColor(red: 0/255, green: 22/255, blue: 60/255, alpha: 1)
} else {
color = UIColor(red: 0/255, green: 22/255, blue: 60/255, alpha: 1)
}
headerCell.setDate(date: rowData.date, color: color)
return headerCell
case 1:
let rowData = addDataArray[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "TimelineCell", for: indexPath) as! TimelineCell
cell.setDrivenKm(drivenKm: rowData.driven)
cell.setConsumedL(consumedL: rowData.consumedL)
cell.setPricePerLiter(pricePerLiter: rowData.pricePerLiter)
return cell
default:
return UITableViewCell()
}
}
}
But if you really want to use a section header, I would use subclass of UITableViewHeaderFooterView for the header.
I have a simple table view showing a list of tasks. I want to show two buttons when user swipes on a cell. A delete button to delete the cell and Completed button to store the task in completed array. I am able to implement the delete button but no idea of showing a second button in the table cell. here is the code.
import UIKit
var taskArray = [String]()
var datesArray = [String]()
class ViewController: UIViewController, UITableViewDataSource
{
#IBOutlet weak var taskTableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return taskArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath)
cell.textLabel?.text = "\(indexPath.row + 1). \(taskArray[indexPath.row])"
cell.detailTextLabel?.text = datesArray[indexPath.row]
return cell
}
override func viewDidLoad()
{
super.viewDidLoad()
taskTableView.dataSource = self
let userDefaults = UserDefaults.standard
if let task = userDefaults.stringArray(forKey: "tasks") , let date = userDefaults.stringArray(forKey: "dates")
{
taskArray = task
datesArray = date
}
print(taskArray)
print(datesArray)
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
taskTableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// this method handles row deletion
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete
{
// remove the item from the data model
taskArray.remove(at: indexPath.row)
datesArray.remove(at: indexPath.row)
// delete the table view row
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
//function to come back from close button
#IBAction func close(segue: UIStoryboardSegue)
{
}
}
Swift 4.0
You can write below method of tableView to define custom swipe action.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .default, title: "Delete") { (action, indexPath) in
}
delete.backgroundColor = UIColor.red
let complete = UITableViewRowAction(style: .default, title: "Completed") { (action, indexPath) in
// Do you complete operation
}
complete.backgroundColor = UIColor.blue
return [delete, complete]
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let more = UITableViewRowAction(style: .normal, title: "More") { action, index in
//self.isEditing = false
print("more button tapped")
}
more.backgroundColor = UIColor.lightGray
let favorite = UITableViewRowAction(style: .normal, title: "Favorite") { action, index in
//self.isEditing = false
print("favorite button tapped")
}
favorite.backgroundColor = UIColor.orange
let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
//self.isEditing = false
print("share button tapped")
}
share.backgroundColor = UIColor.blue
return [share, favorite, more]
}
First make this function return true
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
{
return true
}
it makes your cell editable , apple provides default deleting and editing options that you can use as like this :
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if(editingStyle == .delete)
{
myArray.remove(at: indexPath.item)
table.deleteRows(at: [indexPath], with: .automatic)
table.reloadData()
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
if(studentUser as? String == "Admin")
{
return .delete
}
else
{
return .none
}
}
or you can define your custom ones :
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
let del = UITableViewRowAction(style: .normal, title: "Delete")
{
(action, index) in
let alert = FCAlertView()
alert.makeAlertTypeCaution()
alert.cornerRadius = 10
alert.delegate = self
alert.animateAlertInFromBottom = true
alert.animateAlertOutToTop = true
alert.bounceAnimations = true
alert.blurBackground = true
alert.dismissOnOutsideTouch = true
alert.showAlert(inView: self,
withTitle: "Title you want ",
withSubtitle: "Subtitle Comes here",
withCustomImage: nil,
withDoneButtonTitle:"OK" ,
andButtons:["Cancel"])
}
let edit = UITableViewRowAction(style: .default, title: "Edit")
{
(action, index) in
self.view.makeToast("Editing Coming soon...")
}
del.backgroundColor = AppColor.myNewRedColor
edit.backgroundColor = .lightGray
return [edit,del]
}
Swift 4.0
Add Delegate & DataSource
tableView.delegate = self
tableView.dataSource = self
Add DataSource func "canEditRowAt indexPath"
//MARK: - UITableViewDataSource
public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
Add Delegate func "editActionsForRowAt indexPath"
//MARK: - UITableViewDelegate
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
//Action edit
print("Action Edit...")
})
editAction.backgroundColor = UIColor.gray //Set button color
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
//Action delete
print("Action Delete...")
})
return [deleteAction, editAction]
}
I hope this helps.
As par your Requirement i have . created Demo for you.
Here is the Output,
When you press Delete element will be removed from Array and when you press Add Button element will be added to new Array.
Here is the link of Demo,
Tableview Demo with Swipable Add and Delete
Step 1:- Connect your Tableview datasource and delegate in Storyboard.
Step 2:- Write DataSource Methods of TableView.
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "Preloaded Data"
} else {
return "Added Data to New Array"
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return arrPrelodedData.count
} else {
return arrAddNewData.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "SwipeToDelete", for: indexPath) as? SwipeToDelete else {return UITableViewCell()}
if indexPath.section == 0{
cell.lblCellContent.text = arrPrelodedData[indexPath.row] }
else {
cell.lblCellContent.text = arrAddNewData[indexPath.row]
}
return cell
}
//With this we can edit UITableview ex. Swipe to Delete
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
if indexPath.section == 0 {
return true } else {
return false
}
}
//Select tableview Editing Style (insert and Delete)-> if custom icon than set None
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
//Delete Action 1) Create delete Action 2) Remove data with Indexpath 3) fetch data from coredata 4) delete tableview row 4) set delete button background color 5) return deleteAction in arry wether it is single
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
//Destructive Because we want to delete(destroy) the data from tableview
let deleteAction = UITableViewRowAction(style: .destructive, title: "DELETE") { (rowAction, indexpath) in
self.arrPrelodedData.remove(at: indexPath.row)
tableView.deleteRows(at: [indexpath], with: .automatic)
}
let addAction = UITableViewRowAction(style: .normal, title: "ADD 1") { (rowAction, indexpath) in
self.arrAddNewData.append(self.arrPrelodedData[indexPath.row])
tableView.reloadSections(NSIndexSet(index: 1) as IndexSet, with: .none)
// tableView.reloadRows(at: [indexPath], with: .automatic)
}
deleteAction.backgroundColor = #colorLiteral(red: 1, green: 0.1491314173, blue: 0, alpha: 1)
addAction.backgroundColor = #colorLiteral(red: 0.9176470588, green: 0.662745098, blue: 0.2666666667, alpha: 1)
return [deleteAction,addAction]
}
}
I hope this answer will helpful for you.
Suppose there are 10 row in table view cell if swipe any of the row and after press on the edit action field become editable and remaining row swipe should be disable.
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
{
/*to perform edit action on row*/
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "Edit"){(UITableViewRowAction,NSIndexPath) -> Void in
let cell:SuppliersCutomTableViewCell = tableView.cellForRowAtIndexPath(indexPath) as! SuppliersCutomTableViewCell
print("indexPath",indexPath)
/*making Field Editable method*/
cell.textFieldedit()
}
edit.backgroundColor = UIColor(red: 0.298, green: 0.851, blue: 0.3922, alpha: 1.0);
return [edit]
}
You can use canEditRowAtIndexPath method of UITableViewDataSource for that, declare on Bool instance first like this and use this inside UITableViewDataSource methods.
var allowEdit: Bool = true
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return allowEdit
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
{
/*to perform edit action on row*/
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "Edit"){(UITableViewRowAction,NSIndexPath) -> Void in
let cell:SuppliersCutomTableViewCell = tableView.cellForRowAtIndexPath(indexPath) as! SuppliersCutomTableViewCell
print("indexPath",indexPath)
/*making Field Editable method*/
cell.textFieldedit()
self.allowEdit = false
}
edit.backgroundColor = UIColor(red: 0.298, green: 0.851, blue: 0.3922, alpha: 1.0);
return [edit]
}
Note: Don't forgot to set self.allowEdit to true when your edit done for that cell.
Use the tableView:canEditRowAtIndexPath: method of UITableView and return Bool according to requirement.
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
var canEdit = selectedCell == indexPath.row ? true : false
return canEdit
}
I would like to have a separator between my two UITableViewRowActions. Here is an example of what I would like for my app to look like (this is from Fitbit's app):
Here is what mine looks like:
Here is my code for the actions:
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .Default, title: "Delete") { (action, indexPath) in
//Code for deleting
}
let edit = UITableViewRowAction(style: .Default, title: "Edit") { (action, indexPath) in
//Code for editing
}
edit.backgroundColor = UIColor(red: 0, green: 128/225, blue: 128/225, alpha: 1)
return [delete, edit]
}
How can I achieve this separator? Thank you for your help.