ios - UITableView Cells shifting positions or disappearing entirely on scroll -


i developing , application iphone in swift, , have run peculiar error: in 1 of uitableviewcontrollers,enter code here cells disappear or change sections when scroll , down on table view.

i've been dealing issue few days now, , has prompted me recode entire class, no avail. have researched extensively on error, , believe has data source , how tableview handles it, , have noticed other users have had same problem before, cannot find solution applies problems.

for example, here seems deal cell height, have continued check , double check code, , cell height returns correct values.

in addition, this post talks different errors tableview's data source, have strong pointer datasource's alert array , content , heights correct in cellforrowatindexpath.

this post deals question, doing tableview on main thread.

currently tableview has 4 sections: first, second, , fourth contain 1 cell , third has dynamic amount of cells based on amount of alerts user has added (for example, has 3 alert cells plus 1 "add alert" cell @ bottom). cells affected in 2, 3, , 4 sections.

this tableview should always:

normal view

but, however, here happens when scroll:

i first create variables here:

var currentprayer: prayer! // prayer user editing var prayeralerts: nsmutableorderedset! // mutable set of prayer alerts included in prayer 

then initialize them in viewdidload:

override func viewdidload() {     super.viewdidload()      if currentprayer == nil {         nsexception(name: "prayerexception", reason: "current prayer nil! unable show prayer details!", userinfo: nil).raise()     }      navitem.title = currentprayer.name // sets nav bar title current prayer name     prayeralerts = currentprayer.alerts.mutablecopy() as! nsmutableorderedset // passes currentprayer alerts copy called prayeralerts     prayeralertscount = prayeralerts.count + 1 } 

below tableview methods:

here cellforrowatindexpath:

override func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell {     println("cellforrowatindexpath called \(cellforrowrefreshcount) time")     cellforrowrefreshcount += 1      switch indexpath.section {     case 0:         var cell = tableview.dequeuereusablecellwithidentifier(detailsextendedcellid, forindexpath: indexpath) as! prayerdetailsextendedcell         cell.currentprayer = currentprayer         cell.refreshcell()          return cell      case 1:         var cell = tableview.dequeuereusablecellwithidentifier(setprayerdatecellid, forindexpath: indexpath) as! addprayerdatecell          cell.currentprayer = currentprayer         cell.refreshcell(false, selectedprayer: cell.currentprayer)          return cell      case 2:         if indexpath.row == prayeralerts.count {             var cell = tableview.dequeuereusablecellwithidentifier(addnewalertcellid, forindexpath: indexpath) as! addprayeralertcell             cell.currentprayer = currentprayer             cell.refreshcell(false, selectedprayer: currentprayer)             cell.savebutton.addtarget(self, action: "didsavenewalert", forcontrolevents: .touchdown)              return cell         } else {             var cell = tableview.dequeuereusablecellwithidentifier(prayeralertcellid, forindexpath: indexpath) as! prayeralertcell              let currentalert = prayeralerts[indexpath.row] as! alert             cell.alertlabel.text = alertstore.sharedinstance.convertdatetostring(currentalert.alertdate)              return cell         }      case 3:         var cell = tableview.dequeuereusablecellwithidentifier(answeredprayercellid, forindexpath: indexpath) as! prayeransweredcell         cell.accessorytype = currentprayer.answered == true ? .checkmark : .none          return cell      default:         return uitableviewcell()     } } 

and numberofrowsinsection:

override func tableview(tableview: uitableview, numberofrowsinsection section: int) -> int {     switch section {     case 0: println("returning 1 row section 0"); return 1     case 1: println("returning 1 row section 1"); return 1     case 2: println("returning \(prayeralertscount) rows section 2"); return prayeralertscount     case 3: println("returning 1 row section 3"); return 1     default: println("returning 0 rows section default"); return 0     } } 

and heightforrowatindexpath:

override func tableview(tableview: uitableview, heightforrowatindexpath indexpath: nsindexpath) -> cgfloat {     switch indexpath.section {     case 0: return uitableviewautomaticdimension      case 1:         let cell = tableview.cellforrowatindexpath(indexpath) as? addprayerdatecell          if let thiscell = cell {             let isadding = thiscell.isaddingdate              if isadding {                 if thiscell.selectedtype == prayertype.none || thiscell.selectedtype == prayertype.daily {                     println("selected type none or daily")                     println("returning height of 89 addprayerdatecell")                     return 89                 } else {                     println("returning height of 309 addprayerdatecell")                     return 309                 }             } else {                 println("returning height of 44 addprayerdatecell")                 return 44             }         } else {             println("returning default height of 44 addprayerdatecell")             return 44         }      case 2:         if indexpath.row == prayeralerts.count {             let cell = tableview.cellforrowatindexpath(indexpath) as? addprayeralertcell              if let thiscell = cell {                 let isadding = thiscell.isaddingalert                  if isadding { return 309 }; return 44             } else {                 return 44             }         } else {             return 44         }      case 3: return 44      default: return 44     } } 

and estimatedheightforrowatindexpath:

override func tableview(tableview: uitableview, estimatedheightforrowatindexpath indexpath: nsindexpath) -> cgfloat {     switch indexpath.section {     case 0: return 130     case 1: return 44     case 2: return 44     case 3: return 44     default: return 44     } } 

i have tried editing these methods extensively, checking code in each individual cell. nothing seems work.

does have solutions error? can update more code if necessary, believe either data source problem, or cell's resuse creating error, cannot seem pinpoint anything. in advance help!

update

here addalertcell "refreshcell()" method uitableviewcell extension:

func refreshcell(didselect: bool, selectedprayer: prayer!) {     tableview?.beginupdates()      selectionstyle = didselect == true ? .none : .default      savebutton.hidden = !didselect     cancelbutton.hidden = !didselect     addnewalertlabel.hidden = didselect      isaddingalert = didselect      datelabel.text = alertstore.sharedinstance.convertdatetostring(datepicker.date)      println("addprayeralertcell: cell refreshed")      tableview?.scrollenabled = !didselect     tableview?.endupdates() } 

uitableviewcell extension:

extension uitableviewcell { var tableview: uitableview? {     {         var table: uiview? = superview         while !(table uitableview) && table != nil {             table = table?.superview         }          return table as? uitableview     } } 

}

you shouldn't need call beginupdates / endupdates when refresh cell - these methods used if adding / deleting rows or sections tableview.

what happens if remove beginupdates() , endupdates() calls?


Comments

Popular posts from this blog

python - No exponential form of the z-axis in matplotlib-3D-plots -

php - Best Light server (Linux + Web server + Database) for Raspberry Pi -

c# - "Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types" error when deserializing class -