2017-03-23 10 views
1

Ich verwende Swift 3. Ich habe erweiterbare Tabellenansichtszellen, aber ist es möglich, eine andere Zeilenhöhe zu erhalten, abhängig davon, auf welche Zelle geklickt wurde? Wenn beispielsweise auf die erste Zelle geklickt wird, möchte ich, dass sie 420 für die Höhe zurückgibt, und wenn andere Zellen angeklickt werden, möchte ich, dass sie 300 für die Höhe zurückgibt.Swift 3 - Bedingte erweiterte Tabellenansicht Zellenhöhe

Hier ist meine Zellklasse.

class ResultsCell: UITableViewCell { 

    @IBOutlet weak var introPara : UITextView! 
    @IBOutlet weak var section_heading : UILabel! 

    class var expandedHeight : CGFloat = { get { return 420.0 } } 
    class var defaultHeight : CGFloat { get { return 44.0 } } 

    var frameAdded = false 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     section_heading.translatesAutoresizingMaskIntoConstraints = false 

    } 

    func checkHeight() { 
     introPara.isHidden = (frame.size.height < ResultsCell.expandedHeight) 
    } 

    func watchFrameChanges() { 
     if(!frameAdded) { 
      addObserver(self, forKeyPath: "frame", options: .new, context: nil) 
      checkHeight() 
     } 
    } 

    func ignoreFrameChanges() { 
     if(frameAdded){ 
      removeObserver(self, forKeyPath: "frame") 
     } 
    } 

    deinit { 
     print("deinit called"); 
     ignoreFrameChanges() 
    } 

    // when our frame changes, check if the frame height is appropriate and make it smaller or bigger depending 
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
     if keyPath == "frame" { 
      checkHeight() 
     } 
    } 

} 

Was ich versucht habe, ist so etwas.

var _expandedHeight : CGFloat = 420.0 
class var expandedHeight : CGFloat { get { return _expandedHeight } set (newHeight) { _expandedHeight = newHeight } } 
var isRow0 = false 

override func awakeFromNib() { 
    super.awakeFromNib() 
    section_heading.translatesAutoresizingMaskIntoConstraints = false 

    if isRow0 { 
     ResultsCell.expandedHeight = 300.0 
    } 
    else { 
     ResultsCell.expandedHeight = 420.0 
    } 
} 

Und dann in dem TableViewController ...

// return the actual view for the cell 
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let resultcell = tableView.dequeueReusableCell(withIdentifier: "resultCellTemplate", for: indexPath) as! ResultsCell 

    if indexPath.row == 0 { 
     resultcell.isRow0 = true 
    } else { 
     resultcell.isRow0 = false 
    } 

    return resultcell 
} 

Aber ich bin immer Fehler auf dem Getter/Setter Linie: instance member _expandedHeight cannot be used on type ResultsCell

Wie kann ich das Verhalten erreichen, was ich will?

Antwort

0

Verwenden Tableview-Update-Methoden jeder Zelle Höhe Höhen

self.tableView.beginUpdates() 
self.tableView.endUpdates() 

Änderungen an der Tableview Zellen neu zu bewerten automatisch mit heightForRowAtIndexPath versuchen, Ihre Höhe WRT Einstellung berechnet werden indexPath make Benutzer Sie die heightForRowAtIndexPath erwähnen die berechnen richtige Höhe.

0

Sie sollten dies in der delegate Ihres TableView tun.

Ihr TableView verfügt über eine private Instanzvariable delegate, deren Wert das Protokoll UITableViewDelegate implementieren sollte. Dieses Protokoll enthält viele Funktionen, die das UITableView aufruft, um sein eigenes Aussehen einzustellen.

Für weitere Informationen:

Das UITableViewDelegate Protokoll: https://developer.apple.com/reference/uikit/uitableviewdelegate

Das UITableViewdelegate Instanzvariable: https://developer.apple.com/reference/uikit/uitableview#delegate

Was Sie tun möchten, ist die tableView(_:heightForRowAt:) Methode auf Ihrem UITableViewDelegate Objekt zu implementieren. Diese Methode erhält zwei Parameter: Der erste ist der UITableView selbst, und der zweite ist der IndexPath der Zeile, die für das Rendering vorbereitet wird. Ein IndexPath ist ein Objekt, das die Eigenschaften section und row aufweist, die der gerenderten Zelle entsprechen.

Was Sie tun möchten, ist eine Art der Berechnung, ob eine Zelle erweitert ist oder nicht basiert auf seiner IndexPath.

Swift IndexPath Referenz: https://developer.apple.com/reference/foundation/indexpath

Der Versuch, dies auf der Basis UITableViewCell selbst zu tun ist ein falscher Ansatz, wie Sie sollten in der Regel nicht in die Zelle analysieren, bevor es gemacht wird.

Ein Weg, dies zu tun wäre, dass Ihre UITableView -inheriting-Klasse ein (möglicherweise verschachteltes) Array von Booleans enthält, die angeben, welche Zellen erweitert werden sollen oder nicht. Dann könnten Sie die IndexPathrow und möglicherweise section als Indizes in dieses Array verwenden, um festzustellen, ob die Zelle erweitert ist oder nicht. Etwas wie folgt aus:

class MyTableView: UITableView, UITableViewDelegate { 
    /* ... */ 

    private var expanded: [Bool] = [] 

    init() { 
    super.init() 
    self.delegate = self 
    } 

    func setData(data: [SomeType]) { 
    //set the data for the table here 
    expanded = [Bool](repeating: false, count: data.count) 
    } 

    /* ...logic to expand and collapse cells... */ 

    func tableView(_ view: UITableView, 
       heightForRowAt indexPath: IndexPath) { 
    if expanded[indexPath.row] { 
     return expandedHeight 
    } else { 
     return collapsedHeight 
    } 
    } 

    /* ... */ 
} 

Der richtige Weg, um Ihre Daten zu setzen wäre eine Methode aufrufen auf UITableViewDataSource, aber ich nehme an, dass Sie Daten auf dem Tableview selbst aus Gründen der Einfachheit gesetzt würde.

Versuchen Sie nicht, die Eigenschaften des UITableView von Hand festzulegen. Der delegate und dataSource -basierte Workflow von UITableView ist so eingerichtet, dass Ihre Tabellenansicht effizient arbeitet und sich nur bei Bedarf selbst aktualisiert.

Verwandte Themen