2017-02-22 1 views
1

Ich habe eine UIView innerhalb der Zelle von UITableView. Mein cellForRowAtIndexPath rundet diese Ansicht ab. Wenn ich den Viewcontroller öffne und die Tabelle sehe, werden alle sichtbaren Ansichten gerundet. Wenn ich jedoch nach unten scrolle, hat die erste neue Zelle keine abgerundete Ansicht. Wie repariere ich es?UIView Nicht abgerundet, UITableView Cell Recycling

Mein cellForRowAtIndex sieht wie folgt aus:

let cell = tableView.dequeueReusableCell(withIdentifier: "RepeatingCell", for: indexPath) as! CustomTableViewCell 
cell.delegate = self 
tableView.contentInset = UIEdgeInsetsMake(10, 0, 0, 0) 

if (indexPath as NSIndexPath).row < tableListInfo_Context.count { 
    let task = tableListInfo_Context[(indexPath as NSIndexPath).row     
    let accState = task.value(forKey: "state") as? String 
    //Removed assigning labels their text 
    let mainView = cell.mainView 
    mainView.isHidden = false 
    let circleView = cell.viewToRound 
    circleView?.isHidden = false 
    circleView?.layer.cornerRadius = (circleView?.frame.size.width)!/2 
    circleView?.layer.masksToBounds = true   
    cell.layoutMargins = UIEdgeInsetsMake(0, 1000, 0, 1000) 
} else { 
    //My last cell hides several views to reveal a view under them 
    //If I comment this one line out, I get the not-rounded problem only once and it does not show up again even if I continue scrolling up/down 
    let mainView = cell.mainView 
    mainView.isHidden = true 
    let circleView = cell.viewToRound 
    circleView?.isHidden = true 
} 

Ich verstehe, dass UITableViews recycle Zellen und ich denke, dass wahrscheinlich Probleme mich verursacht. Ich denke, es hängt mit der letzten Zelle zusammen, in der ich meine Ansichten verberge.

In einer Liste mit 20 Zellen wird manchmal eine nicht gerundete Ansicht als erste auf dem Bildschirm angezeigt, manchmal die zweite. Wenn ich nach oben/unten scrolle, wird eine Ansicht zufällig nicht gerundet! Ich weiß, dass es einen Grund/ein Muster gibt, aber ich weiß nicht was.

Ich habe auch versucht, das Hinzufügen des Rundungs ​​Code willDisplayCell:

let circleView = myCell.mainCircle 
circleView?.layer.cornerRadius = (circleView?.frame.size.width)!/2 
circleView?.layer.masksToBounds = true 

jedoch, dass es nicht lösen war. Wie inkonsequent das ist, ist sehr frustrierend. Jede Hilfe wäre willkommen.

FULL CODE DURCH DUNCAN BEANTRAGT:

func buildCell_RepeatableCell (indexPath: IndexPath) -> CustomTableViewCell   { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "RepeatingCell",  for: indexPath) as! CustomTableViewCell 
    cell.delegate = self 

    tableToSV_Left.constant = 10 
    tableToSV_Right.constant = 10 
    tableView.contentInset = UIEdgeInsetsMake(10, 0, 0, 0) 

    if (indexPath as NSIndexPath).row < curLifeList_Context.count { 
     resetDataCell_ToDefaultLaylout(cell: cell, hideExpand: true) 
     let task = curLifeList_Context[(indexPath as NSIndexPath).row] 
     let accState = task.value(forKey: "state") as? String 
     cell.nameLabel!.text = task.value(forKey: "name") as? String 
     cell.descLabel!.text = task.value(forKey: "desc") as? String 
     let redTrashIcon = UIImage(named: "trash") 
     let maskedIcon = redTrashIcon?.maskWithColor(color: .red) 
     cell.row5_LeftBtnImg?.image = maskedIcon 
     let doneGreen = UIColor(colorLiteralRed: 83/255, green: 223/255, blue: 56/225, alpha: 0.9) 
     let greenCheck = UIImage(named: "check_Green") 
     let maskedCheck = greenCheck?.maskWithColor(color: doneGreen) 
     cell.row5_RightBtnImg?.image = maskedCheck 
     roundQtyCircle(view: cell.mainCircle) 
     if accState == "Selected" { 
      cell.circleLine.backgroundColor = doneGreen 
      cell.mainCircle.borderColor = doneGreen 
      cell.hdrCrossOutLine.isHidden = false 
      cell.row5_RightBtnImg.alpha = 0.5 
     } else { 
      cell.circleLine.backgroundColor = UIColor(colorLiteralRed: 211/255, green: 211/255, blue: 211/255, alpha: 0.9) 
      cell.mainCircle.borderColor = UIColor(colorLiteralRed: 211/255, green: 211/255, blue: 211/255, alpha: 0.9) 
      cell.hdrCrossOutLine.isHidden = true 
      cell.row5_RightBtnImg.alpha = 1.0 
     } 
     cell.dataHdr_Left!.text = doneColon_lczd 
     cell.dataHdr_Right!.text = lastDoneColon_lczd 
     cell.dataVal_Left!.text = "0" 
     cell.dataVal_Right!.text = "-" 
     if let lastCompDate = task.value(forKey: "lastCompleted") as? Date { 
      cell.dataVal_Left!.text = "\(task.value(forKey: "timesCompleted") as! Int)" 
      if NSCalendar.current.isDateInToday(lastCompDate) { 
       cell.dataVal_Right!.text = "Today" 
       cell.dataBotDtl_Right.text = "" 
      } else { 
       let secondsUntilChange = (lastCompDate.seconds(from: now)) * -1 
       print("Seconds ago \(secondsUntilChange)") 
       var timeAgo = getDateString(secondsUntilChange, resetDate: lastCompDate) 
       timeAgo.remove(at: timeAgo.startIndex) 
       cell.dataVal_Right!.text = timeAgo 
      } 
     } 
     cell.layoutMargins = UIEdgeInsetsMake(0, 1000, 0, 1000) 
    } else { 
     buildAddNew_ForRepeatableCell(cell: cell) 
    } 

    return cell 
    } 

    func resetDataCell_ToDefaultLaylout (cell: CustomTableViewCell, hideExpand: Bool) { 
    cell.addnewBtn.isHidden = true 
    cell.nameLabel.isHidden = false 
    cell.dataHdr_Left.isHidden = false 
    cell.dataHdr_Right.isHidden = false 
    cell.dataTopDtl_Right.isHidden = false 
    cell.dataBotDtl_Right.isHidden = false 
    cell.mainBox.isHidden = false 
} 

func buildAddNew_ForRepeatableCell (cell: CustomTableViewCell) { 
    cell.addnewBtn.isHidden = false 
    cell.descLabel.text = addNew_lczd //For editor 
    cell.mainBox.isHidden = true 
    cell.layoutMargins = UIEdgeInsetsMake(0, 1000, 0, 1000) 
    cell.container.layoutIfNeeded() 
} 
+0

Im else Block der 'cellForRow' Methode versteckst du' mainView' aber du zeigst es nicht im if Block. – Adeel

+0

@Adeel, das war nur ein Fehler in meinem Entfernen der Text Zuordnung Code, habe ich versehentlich diese unhide Linie entfernt. Wenn die Hauptansicht nicht eingeblendet würde, würde ich die nicht abgerundete Ansicht überhaupt nicht sehen. –

Antwort

0

Statt Schichteigenschaften der Ansicht in cellForRowAtIndexPath der Einstellung, setzen Sie sie in Ihrem CustomTableViewCell Klasse. Sie können sie in awakeFromNib Methode festlegen.

In Kürze bewegen Sie Ihren unteren Code zu awakeFromNib.

let circleView = cell.viewToRound 
    circleView?.layer.cornerRadius = (circleView?.frame.size.width)!/2 
    circleView?.layer.masksToBounds = true 

Der sudo Code könnte so etwas wie dieses:

awakeFromNib(){ 
self.viewToRound?.layer.cornerRadius = (viewToRound?.frame.size.width)!/2 
viewToRound?.layer.masksToBounds = true 

} 
+0

Ich war begeistert von dieser Idee, aber es hat das Problem nicht behoben. Danke für den Vorschlag. –

+0

Gibt es Fehler nach diesem Ansatz? Können Sie mir zeigen, wie Sie meine Lösung implementiert haben? –

+0

Überschreibung func awakeFromNib() { super.awakeFromNib() self.mainCircle? .layer.cornerRadius = (mainCircle? .frame.size.width)!/2 mainCircle? .layer.masksToBounds = true } –

0

dies versuchen, wird es funktionieren.

override func awakeFromNib() { 
     super.awakeFromNib() 
     self.viewToRound?.layer.cornerRadius = (viewToRound?.frame.size.width)!/2 
     viewToRound?.layer.masksToBounds = true 
    } 


override func prepareForReuse() { 
     super.prepareForReuse() 
     self.viewToRound?.layer.cornerRadius = (viewToRound?.frame.size.width)!/2 
     viewToRound?.layer.masksToBounds = true 
    } 
+0

Nein. Ich wusste nicht, dass prepareForReuse existiert. Ich war ziemlich aufgeregt, aber das funktioniert auch nicht. 90% der Zeit sind sie rund, aber immer noch nicht rund, wenn ich schnell und langsam scrolle. –

+0

Können Sie mir teilen Sie Quellcode (Beispielprojekt) wird aktualisiert und Sie mit Lösung wiederherstellen, mit den gleichen Methoden in meiner Antwort – Krunal

0

@Adeel sagte Ihnen bereits das Problem und die Lösung in seinem Kommentar.

Sie müssen immer Ihre Zellen in jedem Fall vollständig konfigurieren. Denken Sie daran, dass wenn Sie eine recycelte Zelle erhalten, sie sich in einem möglichen übrig gebliebenen Zustand befindet.

In Ihrem Fall ist der Schlüssel Bit ist:

if (indexPath as NSIndexPath).row < tableListInfo_Context.count { 
    //Configure cells that are not the last cell 
} else { 
    //Configure cells the last cell 
    mainView.isHidden = true 
} 

Sie verstecken mainView in dem Fall, dass Sie die letzte Zelle gerade konfigurieren, aber nicht un-verstecken, wenn es nicht die letzte Zelle ist. Also, wenn Sie die letzte Zelle konfigurieren, scrollen Sie es aus dem Bildschirm, dann scrollen Sie zurück zum oberen Rand des Bildschirms, wird diese recycelte Zelle für eine indexPath anders als die letzte Zelle wiederverwendet werden, und es ist mainView wird nie nicht versteckt werden.

if (indexPath as NSIndexPath).row < tableListInfo_Context.count { 
    //Configure cells that are not the last cell 
    //----------------------------- 
    // This is what you are missing 
    mainView.isHidden = false 
    //----------------------------- 
} else { 
    //Configure cells the last cell 
    mainView.isHidden = true 
} 

@ VishalSonawane Antwort ist gut, aber diese Arbeit machen Sie zwei unterschiedliche Kennungen, für alle Zellen, aber die letzten, und eine andere Kennung, mit einer Zelle vorkonfiguriert mit Mainview versteckt, man verwenden sollten die letzte Zelle. Auf diese Weise erhalten Sie keine recycelte letzte Zelle und versuchen, sie für eine der anderen Positionen in Ihrer Tabellenansicht zu verwenden.

+0

Hallo Duncan, es tut mir leid, Ihre Zeit damit verschwendet, aber das war nur ein Fehler in meinem Entfernen der Textzuweisungscode für meinen SO Post, habe ich versehentlich diese unausgesprochene Zeile entfernt. Es ist definitiv versteckt. Wenn die Hauptansicht nicht eingeblendet würde, würde ich die nicht abgerundete Ansicht überhaupt nicht sehen. –

+0

Wir können keinen Code debuggen, den wir nicht sehen können. Sie sollten wahrscheinlich Ihre gesamte 'cellForRow (at:)' Methode zeigen. –

+0

In Ordnung, es ist ein bisschen lang, also habe ich versucht, nicht alle zu überwältigen, aber ich habe es einfach hinzugefügt! –