ios - swift table section header duplicating on scroll -
i admitting defeat these custom headers in swift. have tried days prevent labels , images inside of section headers duplicating. on scroll labels/images inside headers duplicate , lay on top of each other.
would please love of god explain me why happening , how fix it.
the circular image keeps creating images , laying them on top of previous, same name , date labels!!
here viewcontroller:
class viewcontroller: uiviewcontroller, uitableviewdelegate, uitableviewdatasource { @iboutlet weak var navigationbar: uinavigationitem! @iboutlet weak var tableview: uitableview! var list = [] var audioplayer:avaudioplayer! override func didreceivememorywarning() { super.didreceivememorywarning() // dispose of resources can recreated. } func getlistbro() -> nsarray { return list } override func viewdidload() { super.viewdidload() // additional setup after loading view, typically nib. tableview.datasource = self; tableview.delegate = self; self.tableview.rowheight = uitableviewautomaticdimension let streamurl = nsurl(string: "http://192.241.174.8:8000/beat-stream-all/")! let stuff = getbeatstream(url:streamurl) self.tableview.rowheight = uitableviewautomaticdimension; self.tableview.estimatedrowheight = 50.0; // stuff.downloadjsonfromurl { (let jsondictionary) in if let jsonlist = jsondictionary["results"] as? nsarray { self.list = jsonlist } let priority = dispatch_queue_priority_default dispatch_async(dispatch_get_global_queue(priority, 0)) { // task dispatch_async(dispatch_get_main_queue()) { // update ui self.tableview.reloaddata() } } } }//end view did load func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecellwithidentifier("streamcell", forindexpath: indexpath) as! streamtableviewcell cell.beatcover.image = uiimage(named: "imgres") if let id = list[indexpath.section] as? nsdictionary { if let beatid = id["id"] as? nsinteger { cell.setid(beatid) } } if let beat_cover = list[indexpath.section] as? nsdictionary { if let beat_cover_image = beat_cover["beat_cover"] as? string { cell.beatcover.downloadimagefrom(link: beat_cover_image, contentmode: uiviewcontentmode.scaletofill) //set image link array. } } if let audio = list[indexpath.section] as? nsdictionary { if let audio_url = audio["audio"] as? string { cell.url = audio_url cell.buildplayer() } } return cell } func tableview(tableview: uitableview, numberofrowsinsection section: int) -> int { return 1 } func numberofsectionsintableview(tableview: uitableview) -> int { return list.count } func tableview(tableview: uitableview, willdisplayheaderview view: uiview, forsection section: int) { let beatauthorlabel = uilabel(frame: cgrectmake(55, 5, 200, 40)) //user pic let profilepictureimageview = uiimageview(frame: cgrectmake(5, 5, 40, 40)); profilepictureimageview.layer.borderwidth = 0 profilepictureimageview.layer.maskstobounds = false profilepictureimageview.layer.bordercolor = uicolor.blackcolor().cgcolor profilepictureimageview.layer.cornerradius = profilepictureimageview.frame.height/2 profilepictureimageview.clipstobounds = true profilepictureimageview.layer.maskstobounds = true profilepictureimageview.image = uiimage(named: "imgres") //set placeholder image first. if let userpicsection = list[section] as? nsdictionary { if let artist = userpicsection["artist"] as? nsdictionary { if let profilepic = artist["profile_pic"] as? string { profilepictureimageview.downloadimagefrom(link: profilepic, contentmode: uiviewcontentmode.scaleaspectfit) } } } if let namesection = list[section] as? nsdictionary { if let name = namesection["artist"] as? nsdictionary { if let adminname = name["admin_name"] as? nsstring { print(adminname) beatauthorlabel.text = adminname string beatauthorlabel.font = uifont(name: beatauthorlabel.font.fontname, size: 14) } } } var datelabel = uilabel(frame: cgrectmake(225, 5, 200, 40)) if let created = list[section] as? nsdictionary { if let date = created["created_at"] as? string { datelabel.text = date string datelabel.font = uifont(name: datelabel.font.fontname, size: 8) } } let header: uitableviewheaderfooterview = view as! uitableviewheaderfooterview header.contentview.addsubview(beatauthorlabel) header.contentview.addsubview(datelabel) header.contentview.addsubview(datelabel) header.contentview.addsubview(profilepictureimageview) header.contentview.backgroundcolor = uicolor(red: 179/255, green: 194/255, blue: 191/255, alpha:1) header.textlabel!.textcolor = uicolor.whitecolor() header.alpha = 1 } func tableview(tableview: uitableview, heightforheaderinsection section: int) -> cgfloat { return 50 } func tableview(tableview: uitableview, didselectrowatindexpath indexpath: nsindexpath) { let indexpath = tableview.indexpathforselectedrow let currentcell = tableview.cellforrowatindexpath(indexpath!)! as! streamtableviewcell currentcell.player.play() } func tableview(tableview: uitableview, didenddisplayingcell cell: uitableviewcell, forrowatindexpath indexpath: nsindexpath) { let leavingcell = cell as! streamtableviewcell leavingcell.player.pause() } }
header views, cells, reused. so, when table view sends tableview(_:willdisplayheaderview:)
, might not first time you've received message header view. yet every time receive message, add 4 subviews it.
don't implement tableview(_:willdisplayheaderview:forsection:)
@ all.
instead, make subclass of uitableviewheaderfooterview
properties different subviews. how created subclass of uitableviewcell
named streamtableviewcell
. maybe call header subview class streamsectionheaderview
. have 2 options setting header view's subviews.
option 1: in streamsectionheaderview.initwithframe(_:)
, create subviews of header view (and store them in instance properties , add them subviews). you're doing in tableview(_:willdisplayheaderview:forsection:)
, move of code streamsectionheaderview
class. register streamsectionheaderview
class table view using uitableview.registerclass(_:forheaderfooterviewreuseidentifier:)
.
option 2: design header view , subviews in xib (you can't in storyboard), connect subviews streamsectionheaderview
properties (which must iboutlet
s in case), , register xib in table view uitableview.registernib(_:forheaderfooterviewreuseidentifier:)
.
to produce section, implement tableview(_:viewforheaderinsection:)
calling tableview. dequeuereusableheaderfooterviewwithidentifier(_:)
, configuring header view's subviews, exist time dequeuereusableheaderfooterviewwithidentifier(_:)
returns.
update
here's streamsectionheaderview
, assuming want set subviews in code:
class streamsectionheaderview: uitableviewheaderfooterview { // make these iboutlets if design streamsectionheaderview in xib. var beatauthorlabel = uilabel(frame: cgrectmake(55, 5, 200, 40)) var profilepictureimageview = uiimageview(frame: cgrectmake(5, 5, 40, 40)) var datelabel = uilabel(frame: cgrectmake(225, 5, 200, 40)) init(frame: cgrect) { profilepictureimageview.layer.borderwidth = 0 profilepictureimageview.layer.maskstobounds = false profilepictureimageview.layer.bordercolor = uicolor.blackcolor().cgcolor profilepictureimageview.layer.cornerradius = profilepictureimageview.frame.height/2 profilepictureimageview.clipstobounds = true profilepictureimageview.layer.maskstobounds = true profilepictureimageview.image = uiimage(named: "imgres") beatauthorlabel.font = uifont(name: beatauthorlabel.font.fontname, size: 14) datelabel.font = uifont(name: datelabel.font.fontname, size: 8) contentview.addsubview(beatauthorlabel) contentview.addsubview(datelabel) contentview.addsubview(profilepictureimageview) contentview.backgroundcolor = uicolor(red: 179/255, green: 194/255, blue: 191/255, alpha:1) textlabel!.textcolor = uicolor.whitecolor() alpha = 1 } required init?(coder adecoder: nscoder) { super.init(coder: adecoder) } }
then, in table view controller:
class viewcontroller: uiviewcontroller, uitableviewdelegate, uitableviewdatasource { override func viewdidload() { super.viewdidload() // blah blah blah other stuff tableview.registerclass(streamsectionheaderview.self, forheaderfooterviewreuseidentifier: "header") } override func tableview(tableview: uitableview, viewforheaderinsection section: int) -> uiview? { let header = tableview.dequeuereusableheaderfooterviewwithidentifier("header") as! streamsectionheaderview if let userpicsection = list[section] as? nsdictionary { if let artist = userpicsection["artist"] as? nsdictionary { if let profilepic = artist["profile_pic"] as? string { header.profilepictureimageview.downloadimagefrom(link: profilepic, contentmode: uiviewcontentmode.scaleaspectfit) } } } if let namesection = list[section] as? nsdictionary { if let name = namesection["artist"] as? nsdictionary { if let adminname = name["admin_name"] as? nsstring { print(adminname) header.beatauthorlabel.text = adminname string } } } if let created = list[section] as? nsdictionary { if let date = created["created_at"] as? string { header.datelabel.text = date string } } return header } }
Comments
Post a Comment