Update Table View in iOS (Swift) -
i making cocktail ios application.
i adding strings tableview (an ingredient "cabinet"). user enters ingredient , presses button add. adds core data not appear right away. doing wrong?
below code, thanks!
viewcontroller:
import uikit import coredata class cabinetviewcontroller: uiviewcontroller, uitextfielddelegate, uitableviewdatasource, uitableviewdelegate { var ingredientarray = [string]() var display = [string]() var dbingredients = [string]() let ingredientfetch = nsfetchrequest(entityname: "cabinet") var fetchedingredient = [cabinet]() @iboutlet weak var textui: uitextfield! @iboutlet weak var button: uibutton! @iboutlet weak var tableview: uitableview! let moc = datacontroller().managedobjectcontext override func viewdidload() { super.viewdidload() textui.delegate = self textui.addtarget(self, action: "textfielddidchange:", forcontrolevents: uicontrolevents.editingchanged) tableview.delegate = self tableview.datasource = self tableview.registerclass(uitableviewcell.self, forcellreuseidentifier: "cell") // fetch core data do{ fetchedingredient = try moc.executefetchrequest(ingredientfetch) as! [cabinet] } catch { fatalerror() } let postendpoint: string = "http://www.thecocktaildb.com/api/json/v1/1/list.php?i=list" guard let url = nsurl(string: postendpoint) else { print("error: cannot create url") return } let urlrequest = nsurlrequest(url: url) let config = nsurlsessionconfiguration.defaultsessionconfiguration() let session = nsurlsession(configuration: config) let task = session.datataskwithrequest(urlrequest, completionhandler: { (data, response, error) in guard let responsedata = data else { print("error: did not receive data") return } guard error == nil else { print("error calling on www.thecocktaildb.com") print(error) return } let post: nsdictionary { post = try nsjsonserialization.jsonobjectwithdata(responsedata, options: []) as! nsdictionary } catch { print("error trying convert data json") return } var count = 1 if let drinks = post["drinks"] as? [nsdictionary] { drink in drinks { if let stringredient = drink["stringredient1"] as? string { print(string(count) + ". " + stringredient) self.dbingredients.append(stringredient) count++ } } } }) task.resume() tableview.reloaddata() } func textfielddidchange(textfield: uitextfield) { search(self.textui.text!) } func textfield(textfield: uitextfield, shouldchangecharactersinrange range: nsrange, replacementstring string: string) -> bool { button.addtarget(self, action: "buttonpressed:", forcontrolevents: .touchupinside) return true } func buttonpressed(sender: uibutton!) { //ingredientarray.append(textui.text!) let entity = nsentitydescription.insertnewobjectforentityforname("cabinet", inmanagedobjectcontext: moc) as! cabinet entity.setvalue(textui.text!, forkey: "ingredient") do{ try moc.save() }catch { fatalerror("failure save context: \(error)") } showalertbuttontapped(button) // dispatch_async(dispatch_get_main_queue(), { () -> void in // self.tableview.reloaddata() // }) } @ibaction func showalertbuttontapped(sender: uibutton) { // create alert let alert = uialertcontroller(title: "added!", message: "you've added " + textui.text! + " cabinet", preferredstyle: uialertcontrollerstyle.alert) // add action (button) alert.addaction(uialertaction(title: "ok", style: uialertactionstyle.default, handler: nil)) // show alert self.presentviewcontroller(alert, animated: true, completion: nil) } func search(str:string) { display.removeall(keepcapacity: false) s in dbingredients{ if s.hasprefix(str){ display.append(s) print(s) } } } func tableview(tableview: uitableview, numberofrowsinsection section: int) -> int { return fetchedingredient.capacity } func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecellwithidentifier("cell", forindexpath: indexpath) do{ let fetchedingredient = try moc.executefetchrequest(ingredientfetch) as! [cabinet] cell.textlabel?.text = fetchedingredient[indexpath.row].ingredient } catch { fatalerror("bad things happened: \(error)") } return cell } func tableview(tableview: uitableview, didselectrowatindexpath indexpath: nsindexpath) { tableview.deselectrowatindexpath(indexpath, animated: true) let alert = uialertcontroller(title: "remove " + fetchedingredient[indexpath.row].ingredient!, message: "no more " + fetchedingredient[indexpath.row].ingredient! + " in cabinet?", preferredstyle: .alert) let deleteaction = uialertaction(title: "remove", style: .default, handler: { (action:uialertaction) -> void in self.fetchedingredient.removeatindex(indexpath.row) do{ let fetchedresults = try self.moc.executefetchrequest(self.ingredientfetch) if let result = fetchedresults[indexpath.row] as? nsmanagedobject { self.moc.deleteobject(result) try self.moc.save() } }catch{ fatalerror() } }) let cancelaction = uialertaction(title: "cancel", style: .default) { (action: uialertaction) -> void in } alert.addaction(cancelaction) alert.addaction(deleteaction) presentviewcontroller(alert, animated: true, completion: nil) tableview.reloaddata() } override func didreceivememorywarning() { super.didreceivememorywarning() // dispose of resources can recreated. } /* // mark: - navigation // in storyboard-based application, want little preparation before navigation override func prepareforsegue(segue: uistoryboardsegue, sender: anyobject?) { // new view controller using segue.destinationviewcontroller. // pass selected object new view controller. } */ }
since problem isn't core data need use table view beginupdates , endupdates insert row. @ end of buttonpressed function put this:
do{ fetchedingredient = try moc.executefetchrequest(ingredientfetch) as! [cabinet] self.tableview.beginupdates() let totalingredients = fetchedingredient.count let newitemindexpath = nsindexpath(forrow: totalingredients-1, insection: 0) self.tableview.insertrowsatindexpaths([newitemindexpath], withrowanimation: uitableviewrowanimation.automatic) self.tableview.endupdates() } catch { fatalerror() }
on number of rows in section:
func tableview(tableview: uitableview, numberofrowsinsection section: int) -> int { return fetchedingredient.count }
and on cell row @ index path
func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecellwithidentifier("cell", forindexpath: indexpath) cell.textlabel?.text = fetchedingredient[indexpath.row].ingredient return cell }
Comments
Post a Comment