ios - Getting duplicate cells with UITableViewController cellForRowAtIndexPath -
i trying create table view using uitableviewcontroller.
the 'cellforrowatindexpath' doesn't seem working right-- have pre-loaded photos , comments parse , put them in array, , want pictures fill screen width, doing manual calculations on them resize.
i doing unusual things table view right, data duplicated.
i know there here i'm not getting, i'm not sure is... maybe need else bind data, or "prepareforreuse" method?
i have included code uitableviewcontroller subclass , uitablecell subclass wrote.
import uikit class youtableviewcell: uitableviewcell { var recipeid:string = "" var recipename:string = "" var imageheight:cgfloat = 0 var labelheight:cgfloat = 0 // need this? override func prepareforreuse() { self.textlabel!.text = recipeid //put label name self.imageview!.image = nil } override func setselected(selected: bool, animated: bool) { super.setselected(selected, animated: animated) // configure view selected state } } class youtableviewcontroller: basetableviewcontroller { // uitableviewcontroller { var labelcreated = [bool]() var imagecreated = [bool]() var cellarray = [int:youtableviewcell]() override func viewdidload() { super.viewdidload() self.tableview.delegate = self self.tableview.datasource = self self.view.addgesturerecognizer(self.revealviewcontroller().pangesturerecognizer()) if !isyoudataloaded { _ = datacontroller.getyoupagedata() } // initialize height arrays _ in 0..<youfeed.count { labelcreated.append(false) imagecreated.append(false) } // uncomment following line preserve selection between presentations // self.clearsselectiononviewwillappear = false // uncomment following line display edit button in navigation bar view controller. // self.navigationitem.rightbarbuttonitem = self.editbuttonitem() self.navigationcontroller?.settoolbarhidden(false, animated: false) } // ... skipping down override func tableview(tableview: uitableview, numberofrowsinsection section: int) -> int { // return feedarray.count return youfeed.count } override func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell { print("cellforrowatindexpath : \(indexpath.row)") // reference cell cellarray[indexpath.row] = (tableview.dequeuereusablecellwithidentifier("cell", forindexpath: indexpath) as! youtableviewcell) let thiscell:youtableviewcell = cellarray[indexpath.row]! // temp -- border thiscell.layer.borderwidth = 2.0 thiscell.layer.bordercolor = uicolor.blackcolor().cgcolor let meal = youfeed[indexpath.row].recipe // if image exists if let foodimage:uiimage = meal.imageview.image! uiimage { var namelabel:uilabel = uilabel() var fitimageview:uiimageview? if imagecreated[indexpath.row] == false { print("for image #\(indexpath.row)") fitimageview = layouthelper.fitimageincell(foodimage, cell: thiscell, name: meal.recipename) thiscell.contentview.addsubview(fitimageview!) thiscell.imageheight = fitimageview!.frame.height fitimageview!.frame.origin.y = 0 print("img height : \(fitimageview!.image!.size.height)") imagecreated[indexpath.row] = true } if labelcreated[indexpath.row] == false { // create label var captionstring = "" if let mealnametext:string = meal.recipename string { captionstring += mealnametext } if let posttext:string = meal.desc string { captionstring += "\n" + posttext } else { print("meal desc null") } if let numforks:int = meal.forks int { captionstring += "\n" + string(numforks) + " forks" } if (fitimageview != nil) { namelabel = layouthelper.fitlabelbelowimageview(captionstring, imageview: fitimageview!, cell: thiscell, yoffset: 0) thiscell.addsubview(namelabel) thiscell.labelheight = namelabel.frame.height } } } return thiscell } override func tableview(tableview: uitableview, heightforrowatindexpath indexpath: nsindexpath) -> cgfloat { let thiscell = cellarray[indexpath.row] var thisht:cgfloat = 0 if thiscell != nil { thisht = thiscell!.labelheight + thiscell!.imageheight } return thisht } }
when re-use cells (which thing do!) must re-initialize entire cell every time cellforrowatindexpath
called. because possible when make call:
tableview.dequeuereusablecellwithidentifier
it returning cell have initialized. example, let's have 4 rows visible on screen:
row 1 - cell [image 1] row 2 - cell b [image 2] row 3 - cell c [image 3] row 4 - cell d [image 4]
now, let's scroll down , row 1 no longer on screen, row 5 has appeared. possible cell receive row 5 same exact cell @ row 1. so, after call tableview.dequeuereusablecellwithidentifier
row 5 looks this:
row 2 - cell b [image 2] row 3 - cell c [image 3] row 4 - cell d [image 4] row 5 - cell [image 1] <--
you need update cell point image 5. may work fine in code , this:
row 2 - cell b [image 2] row 3 - cell c [image 3] row 4 - cell d [image 4] row 5 - cell [image 5] <--
now, let's scroll , row 1 assigned cell again:
row 1 - cell [image 5] <-- row 2 - cell b [image 2] row 3 - cell c [image 3] row 4 - cell d [image 4]
since storing arrays keep track of rows have been initialized (imagecreated
, labelcreated
) cell won't updated point image 1:
// true, not execute if imagecreated[indexpath.row] == false
this means rid of imagecreated
, labelcreated
arrays , perform code initialize cells every time cellforrowatindexpath
called.
also, recommend getting rid of cellarray
, not storing references cells (for same reasons mentioned above). can cache cell heights , should fine because not tied re-usable cells. this:
var cellheightarray = [int:cgfloat]()
since doing calculations in cellforrowatindexpath
set height @ bottom:
cellheightarray[indexpath.row] = thiscell!.labelheight + thiscell!.imageheight;
then set array in heightforrowatindexpath
:
override func tableview(tableview: uitableview, heightforrowatindexpath indexpath: nsindexpath) -> cgfloat { let thiscellheight = cellheightarray[indexpath.row] var thisht:cgfloat = 0 if thiscellheight != nil { thisht = thiscellheight } return thisht }
by default, believe heightforrowatindexpath
called before cellforrowatindexpath
. in case of cells have height of 0 until reload tableview. @ post more information:
why heightforrowatindexpath: come before cellforrowatindexpath:?
Comments
Post a Comment