deleting rows and sections from UITableView swift - swift

I am trying to swipe to delete cells from my tableview and every time I attempt to do so I get an error.
This is my code for the actual deletion
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
self.tableView.beginUpdates()
self.feedData.removeObjectAtIndex(indexPath.row) // also remove an array object if exists.
self.tableView.deleteRowsAtIndexPaths(NSArray(object: NSIndexPath(forRow: indexPath.row, inSection: 1)) as [AnyObject], withRowAnimation: UITableViewRowAnimation.Left)
// self.tableView.deleteRowsAtIndexPaths(NSArray(object: NSIndexPath(forRow: indexPath.row, inSection: 1)) as [AnyObject], withRowAnimation: UITableViewRowAnimation.Left)
self.tableView.endUpdates()
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
And this is what I am returning in my sections
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
I am a beginner so bear with me :)

You need to put the following two functions to handle swipe deletion:
func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
return true
}
func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
if (editingStyle == .Delete) {
// handle delete (by removing the data from your array and updating the tableview)
self.tableView.beginUpdates()
self.feedData.removeObjectAtIndex(indexPath.row) // also remove an array object if exists.
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Left)
self.tableView.endUpdates()
}
The function tableView(_:canEditRowAtIndexPath:) according to Apple:
Permits the data source to exclude individual rows from being treated as editable. Editable rows display the insertion or deletion control in their cells. If this method is not implemented, all rows are assumed to be editable. Rows that are not editable ignore the editingStyle property of a UITableViewCell object and do no indentation for the deletion or insertion control. Rows that are editable, but that do not want to have an insertion or remove control shown, can return UITableViewCellEditingStyleNone from the tableView:editingStyleForRowAtIndexPath: delegate method.
I hope this help you.

Related

How to delete specific rows in a table view cell?

I am using a table view which consists of three sections. User can delete the rows for third section. But while I am using table view delegate method for deleting rows ,It is affecting for other sections. So how could I overcome from this problem?
Here is my code
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
numbers.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
If you want to restrict editing to section 2 implement canEditRowAt (code is Swift 3+)
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return indexPath.section == 2
}
Or add a check
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete && indexPath.section == 2 {
numbers.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
In function with forRowAt indexPath: IndexPath you have IndexPath value.
It contains .section. So, you can simply check, which section have you selected and then do or not do deleting.
To delete rows for specific section:
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
Hope it helps
correct way of doing this is
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return indexPath.section == 2
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete && indexPath.section == 2
{
yourArray.remove(at: indexPath.row)
yourtable.reloadData()
}
}

Swipe to delete cell without having to press delete button Swift

In Swift. How can I add a swipe to delete on cell (still showing the color and label of delete) but as the swipe is ended it does the delete action. I saw the same questioned answered elsewhere but was for objective c. I'm not sure if swift has any new implementation for this. Any help would be great.
Thanks
you can make use of these two methods other than the basic UITableView implementations :
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
objects.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}

Deleting table cell populated with Dictionary (Swift)

I'm trying to add functionality so the user can delete a table cell. However, this table cell is populated using a dictionary so I'm getting an error message: "cannot invoke 'removeAtIndex' with an argument list of type {index: Int)
Here's my code:
var titles = [Int: String]()
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
titles.removeAtIndex(index: indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
You need to call removeValueForKey method, because you use Int as keys. The
An you need to add beginUpdates and endUpdates method calls as well to perform the animations.
See the code below:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
table.beginUpdates()
titles.removeValueForKey(index: indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
table.endUpdates()
}
}
Note: in such a case, consider using Array instead of Dictionary? You don't actually need dictionary since it will be indexed from row 0 to row count-1, right?

Move all views up after hiding one

In my Android app, I was able to create use a standard table with rows and have text boxes in it. Based on user preferences, some of these rows are shown/hidden. For example if the user doesn't want to enter in cash/credit sales, or track any discounts given to a customer, etc, these fields shouldn't appear.
I simply would hide the entire row, and just like a DIV in html, the rest of the rows would move up nicely.
So for example:
element1
element2
element3
I'd want to remove element 2, and 3 moves up and takes 2's place. I'll probably have 8 of these fields btw.
In iOS, however, is something like this possible? Some googling yielded results that more or less made this seem very complicated for showing/hiding form elements and having everything slide up nicely. Some solutions included setting up very complex autolayout scenarios dynamically, or not using autolayout at all, etc. Then again, these solutions were for older versions of ios.
Is something like this possible? How could I achieve this?
Thanks!
Use UITableView.
UITableView allows you to represent list of cells and manipulate them (add, remove, reorder) with animations.
In you case every option will be a UITableViewCell.
Create a subclass of UITableViewController
Set a dataSource of UITableView
Implement UITableViewDataSource
That is 2 functions
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell
Update TableView items
You can easily reload tableView by editing your objects and calling reloadData method on tableView
// Add, remove or replace your objects you want to display in table View
objects = ["1", "2", "3"]
// call tableView to reload it's data. TableView will call dataSource delegates methods and update itself
tableView.reloadData()
You can remove or add specific item in tableView
First update your object, by removing or adding it, than call update tableView and say what cell (at which position) it should add or remove. You can also say what type of animation it should use
var index = 2
// Update your object Model, here we remove 1 item at index 2
objects.removeAtIndex(index)
// saying tableView to remove 1 cell with Fade animation.
tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: 0)], withRowAnimation: .Fade)
Here is full Code example
class MasterViewController: UITableViewController {
var objects = ["Option 1", "Option 2", "Option 3"]
func insert(obj: String, at: Int) {
objects.append(obj)
let indexPath = NSIndexPath(forRow: at, inSection: 0)
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
func deleteAt(index: Int) {
objects.removeAtIndex(index)
tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: 0)], withRowAnimation: .Fade)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func insertNewObject(sender: AnyObject) {
insert(NSDate.date().description, at: 0)
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objects.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let object = objects[indexPath.row]
cell.textLabel?.text = object
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
deleteAt(indexPath.row)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}

Swift - Reorder UITableView cells

I do know that it's not too hard to do it in objective C , the problem is I'm learning Swift by skipping Objective C.
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/ManageReorderRow/ManageReorderRow.html
However is there anything equivalent to the link above in Swift?
I have tried this...here is the code
In my example code there is button that starts the editing ---
Action Method of the button -->
#IBAction func editTableView (sender:UIBarButtonItem)
{
if listTableView.editing{
//listTableView.editing = false;
listTableView.setEditing(false, animated: false);
barButton.style = UIBarButtonItemStyle.Plain;
barButton.title = "Edit";
//listTableView.reloadData();
}
else{
//listTableView.editing = true;
listTableView.setEditing(true, animated: true);
barButton.title = "Done";
barButton.style = UIBarButtonItemStyle.Done;
//listTableView.reloadData();
}
}
And the related UITableView delegate methods -->
// The editing style for a row is the kind of button displayed to the left of the cell when in editing mode.
func tableView(tableView: UITableView!, editingStyleForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCellEditingStyle
{
if (false == self.editing && !indexPath){
return UITableViewCellEditingStyle.None;
}
if (self.editing && indexPath.row == countryList.count){
return UITableViewCellEditingStyle.Insert;
}
else{
return UITableViewCellEditingStyle.Delete;
}
//return UITableViewCellEditingStyle.Delete;
}
// Update the data model according to edit actions delete or insert.
func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!)
{
if editingStyle == UITableViewCellEditingStyle.Delete{
countryList.removeAtIndex(indexPath.row);
self.editTableView(barButton);
listTableView.reloadData();
}
else if editingStyle == UITableViewCellEditingStyle.Insert{
countryList.append("New Country");
}
}
// Determine whether a given row is eligible for reordering or not.
func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -> Bool
{
return true;
}
// Process the row move. This means updating the data model to correct the item indices.
func tableView(tableView: UITableView!, moveRowAtIndexPath sourceIndexPath: NSIndexPath!, toIndexPath destinationIndexPath: NSIndexPath!)
{
let item : String = countryList[sourceIndexPath.row];
countryList.removeAtIndex(sourceIndexPath.row);
countryList.insert(item, atIndex: destinationIndexPath.row)
}
You can also download full code Here
All the same rules apply as in Objective-C. You set the table view data source and delegate just like you would in Objective-C.
func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
return true // Yes, the table view can be reordered
}
func tableView(tableView: UITableView!, moveRowAtIndexPath fromIndexPath: NSIndexPath!, toIndexPath: NSIndexPath!) {
// update the item in my data source by first removing at the from index, then inserting at the to index.
let item = items[fromIndexPath.row]
items.removeAtIndex(fromIndexPath.row)
items.insert(item, atIndex: toIndexPath.row)
}
If you need finer grain control, you can also implement
func tableView(tableView: UITableView!, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath!, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath!) -> NSIndexPath! {
…
}
Now there is a library for this reorder function: LPRTableView.
Converted Above Answer methods in Swift 3.0
// Determine whether a given row is eligible for reordering or not.
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
// Process the row move. This means updating the data model to correct the item indices.
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item : Dictionary<String, Any> = arrInterval[sourceIndexPath.row]
arrInterval.remove(at: sourceIndexPath.row)
arrInterval.insert(item, at: destinationIndexPath.row)
}