Not able to show Delete button - swift2

I am trying to implement an alarm clock app just like apple's Clock app.On the click of Edit button on the left hand side I want to make table enter into Editing mode with red circles on left side of every cell(custom UITableViewCell) And on the click of that red circle want to show "Delete" button/action on the right side.
I have been trying a lot and went through many sites but still could not figure out. Can someone please see what mistake I am making?
I have referred below and many others links:
How to enable swipe to delete cell in a TableView?
UITableViewCell, show delete button on swipe
class SavedAlarmListViewController: UIViewController,UITableViewDataSource,UITableViewDelegate{
#IBOutlet weak var tableView: UITableView!
var alarms = [AlarmDataObject]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.navigationItem.leftBarButtonItem = self.editButtonItem()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
refreshList()
}
func refreshList() {
alarms = AlarmsList.sharedInstance.allSavedAlarms()
tableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return alarms.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AlarmTableViewCell
// custom code to set data ....
return cell
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true // all cells are editable
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let alarm = alarms.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
AlarmsList.sharedInstance.removeAnAlarm(alarm)
}
}
}
class AlarmTableViewCell:UITableViewCell {
// IBOutlets
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}

You should implement
tableView(_:editingStyleForRowAtIndexPath:) and return .Delete

Related

How do you edit or delete text in a tableView?

I am trying have the user to modify/delete default text in a tableview, I have tried the following code witch works but as soon as the user goes to the other view controller and back (or leaves the app and comes back), the text goes back to being the default text.
How could I have it work?
I have posted the entire code for the tableView so you can have an overview of what I could have done wrong.
thank you !
var places = [Dictionary<String,String>()]
var activePlace = -1
class TableViewController: UITableViewController {
func companyNameUpdatedAlert(title: String, error: String, indexPath: Int) {
let alert = UIAlertController(title: title, message: error, preferredStyle: UIAlertControllerStyle.Alert)
alert.addTextFieldWithConfigurationHandler { (textField) -> Void in
textField.placeholder = "Enter new text"
}
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
let lat = places[indexPath]["lat"]!
let lon = places[indexPath]["lon"]!
places.removeAtIndex(indexPath)
places.insert(["name" : alert.textFields![0].text!, "lat" : lat, "lon" : lon], atIndex: indexPath)
self.tableView.reloadData()
}))
self.presentViewController(alert, animated: true, completion: nil)
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let changeText = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Change text" , handler: { (action:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
self.companyNameUpdatedAlert("Update text", error: "enter text below", indexPath: indexPath.row)
})
let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete" , handler: { (action:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
places.removeAtIndex(indexPath.row)
tableView.reloadData()
})
return [changeText, deleteAction]
}
override func viewDidLoad() {
//save start
if NSUserDefaults.standardUserDefaults().objectForKey("places") != nil {
places = NSUserDefaults.standardUserDefaults().objectForKey("places") as! [Dictionary]
//save stop
super.viewDidLoad()
if places.count == 1 {
places.removeAtIndex(0)
places.append(["name":"Long press on map to add location","lat":"90","lon":"90"])
}
if NSUserDefaults.standardUserDefaults().objectForKey("places") != nil {
places = NSUserDefaults.standardUserDefaults().objectForKey("places") as! [Dictionary]
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return places.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = places[indexPath.row]["name"]
return cell
}
override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
activePlace = indexPath.row
return indexPath
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "newPlace" {
activePlace = -1
}
}
override func viewWillAppear(animated: Bool) {
tableView.reloadData()
}
}
When you edit the table you should persist your data in the NSUserDefaults. Otherwise you are just changing the class property which is reloaded from the original NSUserDefaults each time the class loads.
Try this inside your UIAlertAction closure:
NSUserDefaults.standardUserDefaults().setObject(places, forKey: "places")
NSUserDefaults.standardUserDefaults().synchronize()

Why this UITableViewController doesn't show anything?

I'm using the latest beta of Xcode 7. I'm programming a simple UITableView, but this doesn't work well, the inspector error doesn't show anithing but when I start the simulator, the App crash. Can someone help me?
// RestaurantTableViewController.swift
import UIKit
class RestaurantTableViewController: UITableViewController {
var restaurantNames = ["Cafe Deadend", "Homei", "Teakha", "Cafe Loisl", "Petite Oyster", "For Kee Restaurant", "Po's Atelier", "Bourke Street Bakery", "Haigh's Chocolate", "Palomino Espresso","Upstate","Traif","Graham Avenue Meats","Waffle & Wolf", "Five Leaves", "Cafe Lore", "Confessional", "Barrafina", "Donostia", "Rpyal Oak", "Thai Cafe"]
var restaurantImages = ["cafedeadend.jpg", "homei.jpg", "teakha.jpg", "cafeloisl.jpg",
"petiteoyster.jpg", "forkeerestaurant.jpg", "posatelier.jpg", "bourkestreetbakery.jpg",
"haighschocolate.jpg", "palominoespresso.jpg", "upstate.jpg", "traif.jpg",
"grahamavenuemeats.jpg", "wafflewolf.jpg", "fiveleaves.jpg", "cafelore.jpg",
"confessional.jpg", "barrafina.jpg", "donostia.jpg", "royaloak.jpg", "thaicafe.jpg"]
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return self.restaurantNames.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
// Configure the cell...
cell.textLabel!.text = restaurantNames[indexPath.row]
cell.imageView?.image = UIImage(named: restaurantImages[indexPath.row])
return cell
}
}

AnyObject is not convertible to UITableViewCell

I'm using the Beginning Swift Programming book by AppCoda and I can't seem to figure out what is wrong with this block of code.
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var restaurantNames = ["Cafe Deadend", "Homei", "Teakha", "CafeLoisl", "Petite Oyster", "For Kee Restaurant", "Po's Atelier", "Bourke Street Bakery", "Haigh’s Chocolate", "Palomino Espresso", "Upstate", "Traif", "Graham Avenue Meats And Deli", "Waffle & Wolf", "Five Leaves", "Cafe Lore", "Confessional", "Barrafina", "Donostia", "Royal Oak", "CASK Pub and Kitchen"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return restaurantNames.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
// Configure the cell...
cell.textLabel.text = restaurantNames[indexPath.row]
return cell
}
}
This line is throw a 'AnyObject is not convertible to 'UITableViewCell'
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
I'm really new to Swift and iOS programming in general so any help would be appreciated.
You need to change as to as!
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
Also make sure that you have added a prototype cell to your storyboard with the reusable string name "Cell"
//MARK: Tableview
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
{
return tabledata.count
}
func tableView(tableView: UITableView!,
cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.Default, reuseIdentifier:"Cell")
cell.textLabel?.text = tabledata[indexPath.row]
return cell
}
I have used this code for tableview....You can change this according to your need.Even I'm new in swift or else I would've correct your code.

Moving Row inside a Table View with tap - Swift

I'm try to simulate the dragging of the cell with the single tap on the cell.
Once tapped the single cell has to be the first item in the list.
I tried with ll the method but my indexpath change but I don't see the result in the table, even if i reload it.
Any Suggestion?
here's my code:
import UIKit
var array = ["1", "2", "3", "4", "5", "6"]
class Table: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.setEditing(true, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel.text = array[indexPath.row]
return cell
}
var indexPathForCell = NSIndexPath(forRow: 0, inSection: 0)
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPathForCell: NSIndexPath) {
tableView.reloadData()
println(indexPathForCell)
//
}
override func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath indexPathForCell: NSIndexPath) {
println(indexPathForCell)
}
}
Thank you
To swap a cell's position animated, you'll need to update your data source and the tableView's representation at the same time. You can do that like this:
table.beginUpdates()
table.moveRowAtIndexPath(indexPath, toIndexPath: NSIndexPath(forRow: 0, inSection: 0))
array.insert(array.removeAtIndex(indexPath.row), atIndex: 0)
table.endUpdates()

exc_bad_access code=exc_i386_gpflt when deleting cell in TableView

In xcode 6 while deleting cell in my to do list i randomly get an error
"exc_bad_access code=exc_i386_gpflt"
i have got a two views - on second i enter items in array "toDoList"
In first i show all item from "toDoList" and have an option to delete when, code of first page in this:
import UIKit
var toDoList: [String] = []
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//var cell = UITableViewCell()
#IBOutlet weak var itemList: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return toDoList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel.text = toDoList[indexPath.row]
return cell
}
override func viewWillAppear(animated: Bool) {
if var storedItems: AnyObject = NSUserDefaults.standardUserDefaults().objectForKey("items"){
toDoList = []
for var i = 0; i < storedItems.count; ++i{
toDoList.append(storedItems[i] as NSString)
}
}
itemList.reloadData()
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){
if editingStyle == UITableViewCellEditingStyle.Delete{
toDoList.removeAtIndex(indexPath.row)
let saveData = toDoList
NSUserDefaults.standardUserDefaults().setObject(saveData, forKey: "items")
NSUserDefaults.standardUserDefaults().synchronize()
itemList.reloadData()
}
}
}
What's causing your error is
itemList.reloadData()
in your function
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
So to fix your problem, remove that line and then add this line after toDoList.removeAtIndex(indexPath.row):
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
What this method does is: Deletes the rows specified by an array of index paths, with an option to animate the deletion. (from Xcode Quick Help)

Resources