2017-04-10 2 views
1

Ich habe eine xib für eine UITableViewCell erstellt, die in bestimmten Fällen Ansichten hinzugefügt werden.UITableCell Höhe ist nicht korrekt

Es muss die Höhe entsprechend der Anzahl der Ansichten, die der Zelle hinzugefügt werden, korrekt angepasst werden.

Was ich getan habe, ist die folgende enter image description here Die UIImage und UILabel eine bottom constraint haben, die auf die top des UIView

Der UIView gesetzt wird, hat eine height constraint die equal to or greater then 0 ist. Wenn also keine Ansichten zur Zelle hinzugefügt werden, müssen sie 0 sein. Wenn Zellen zur Zelle hinzugefügt werden, müssen sie richtig dimensioniert werden.

Der Code für meine Zelle sieht wie folgt aus

struct MenuTableCellContents { 
    var identifier: cellIdentifier 
    var cellImage: UIImage 
    var cellText: String 
    //var cellFont: UIFont 
    var cellTextColor: UIColor 
    var subCells: [MenuTableCellContents]? 

    /// Normal cells without subcells 
    init(identifier: cellIdentifier, cellImage: UIImage, cellText: String, /*cellFont: UIFont,*/ cellTextColor: UIColor) { 
     self.identifier = identifier 
     self.cellImage = cellImage 
     self.cellText = cellText 
     self.cellTextColor = cellTextColor 
     //self.cellFont = cellFont 
    } 

    /// Cells with subcells 
    init(identifier: cellIdentifier, cellImage: UIImage, cellText: String, /*cellFont: UIFont,*/ cellTextColor: UIColor, subCells: [MenuTableCellContents]) { 
     self.identifier = identifier 
     self.cellImage = cellImage 
     self.cellText = cellText 
     self.cellTextColor = cellTextColor 
     //self.cellFont = cellFont 
     self.subCells = subCells 
    } 

    enum cellIdentifier { 
     case standard 
     case noIcon 
     case subcell 
    } 
} 

class MenuTableCell: UITableViewCell { 

    @IBOutlet var cell_icon: UIImageView! 
    @IBOutlet var cell_label: UILabel! 
    @IBOutlet var cell_contentView: UIView! 
    @IBOutlet var cell_contentView_height: NSLayoutConstraint! 


    var cellImage: UIImage? 
    var cellText: String? 
    var cellTextColor: UIColor? 
    //var cellFont: UIFont? 

    var subCells: [MenuTableCellContents]? 

    private var contentViewHeight: CGFloat? 

    override func draw(_ rect: CGRect) { 
     drawSubCells() 
     cell_label.text = cell_label.text?.uppercased() 

     super.draw(rect) 
    } 

    /// draw the subcells when needed 
    func drawSubCells() { 
     // Check if there are subcells 
     if let cells = subCells { 
      let count = CGFloat(cells.count) 

      // Set the height for the subcells 
      contentViewHeight = 40 * count 
      let contentViewFrame = CGRect(x: self.frame.width, y: self.cell_contentView.frame.origin.y, width: self.frame.width, height: contentViewHeight!) 
      cell_contentView?.frame = contentViewFrame 

      var i = 0 
      for cell in cells { 

       // create a view for each cell 
       let cellView = UIView() 
       let cellFrame = CGRect(x: 0, y: CGFloat(i * 40), width: contentViewFrame.width, height: 40) 
       cellView.frame = cellFrame 

       // add a image view to each cell 
       let imageView = UIImageView(image: cell.cellImage) 
       let imageViewFrame = CGRect(x: 0, y: (cellFrame.height - cellFrame.height/2)/2, width: cellFrame.width * 0.2, height: cellFrame.height/2) 
       imageView.frame = imageViewFrame 
       imageView.contentMode = .scaleAspectFit 

       // add a button to each cell 
       let cellLabel = UILabel() 
       let cellLabelFrame = CGRect(x: imageViewFrame.width, y: 0, width: cellFrame.width - imageViewFrame.width, height: 40) 
       cellLabel.frame = cellLabelFrame 
       //cellLabel.font = cell.cellFont 

       cellLabel.text = cell.cellText.uppercased() 
       cellLabel.textColor = cell.cellTextColor 
       cellLabel.minimumScaleFactor = 15 


       // add the imageview and button to the subcell view 
       cellView.addSubview(imageView) 
       cellView.addSubview(cellLabel) 

       // add the subcell to the cell 
       cell_contentView?.addSubview(cellView) 
       i += 1 
      } 

      setupConstraints(height: contentViewHeight!) 
     } 
    } 

    /// Set the height constraint for the cell content view in which the subcells reside 
    func setupConstraints(height: CGFloat) { 
     cell_contentView.frame.size.height = height 
    } 
} 

dann als meine Tabelle Methoden suchen

class MenuViewController: UIViewController, UITableViewDelegate { 
    @IBOutlet var menu_table: MenuTableView! 

    var cellContent: [MenuTableCellContents] = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     setupCells() 


     let menuCell = UINib(nibName: "MenuTableCell", bundle: nil) 
     menu_table.register(menuCell, forCellReuseIdentifier: "menuCell") 

     menu_table.delegate = self 
     menu_table.dataSource = self 
     menu_table.rowHeight = UITableViewAutomaticDimension 
     menu_table.estimatedRowHeight = 50 

     self.revealViewController().frontViewShadowRadius = 0 
     self.revealViewController().frontViewShadowOffset = CGSize.zero 
    } 

    /// setup the required cells for the menu 
    func setupCells() { 
     let normal1 = MenuTableCellContents(identifier: .standard, cellImage: UIImage(named: "icn_pin")!, cellText: "normal1", cellTextColor: UIColor.black) 
     let normal2 = MenuTableCellContents(identifier: .standard, cellImage: UIImage(named: "icn_pin")!, cellText: "normal2", cellTextColor: UIColor.black) 
     let normal3 = MenuTableCellContents(identifier: .standard, cellImage: UIImage(named: "icn_pin")!, cellText: "normal3", cellTextColor: UIColor.black) 

     let sub1 = MenuTableCellContents(identifier: .subcell, cellImage: UIImage(named: "icn_pin")!, cellText: "sub1", cellTextColor: UIColor.black) 
     let sub2 = MenuTableCellContents(identifier: .subcell, cellImage: UIImage(named: "icn_pin")!, cellText: "sub2", cellTextColor: UIColor.black) 
     let sub3 = MenuTableCellContents(identifier: .subcell, cellImage: UIImage(named: "icn_pin")!, cellText: "sub3", cellTextColor: UIColor.black) 
     let subs = MenuTableCellContents(identifier: .standard, cellImage: UIImage(named: "icn_pin")!, cellText: "subs", cellTextColor: UIColor.black, subCells: [sub1, sub2, sub3]) 


     let normal4 = MenuTableCellContents(identifier: .standard, cellImage: UIImage(named: "icn_pin")!, cellText: "normal4", cellTextColor: UIColor.black) 


     cellContent = [normal1, normal2, normal3, subs, normal4] 
    } 
} 

/// required methods for the uitableview 
extension MenuViewController: UITableViewDataSource { 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return cellContent.count 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let content = cellContent[indexPath.item] 

     let cell = menu_table.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) as! MenuTableCell 

     cell.cell_icon.image = content.cellImage 
     cell.cell_label.text = content.cellText 
     cell.cell_label.textColor = content.cellTextColor 
     //cell.cell_label.font = content.cellFont 

     if let subCells = content.subCells { 
      cell.subCells = subCells 
     } 

     return cell 
    } 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 

    } 

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return UITableViewAutomaticDimension 
    } 
} 
folgt

weiß jemand, wo ich falsch gehe? Die Größe wird nicht korrekt angepasst, wenn die Ansichten hinzugefügt werden. Die Höhe bleibt Null.

UPDATE

ich ein Testprojekt mit dem Thema GitHub hochgeladen haben. https://github.com/MaikoHermans/tableCellDynamicHeightProblem

UPDATE 2

Für alle vor dem gleichen Problem ich das GitHub Projekt in Update 1 auf die Arbeits erwähnt aktualisiert haben.

+0

Ihr Etikett wachsen? oder seine Höhe ist festgelegt ?, wenn Sie behoben sind, können Sie Ihre Zellenhöhe als 40 * Anzahl der Unteransichten + Label Höhe berechnen –

Antwort

1

Zunächst müssen Sie eine benutzerdefinierte Klasse für Ihre UIView erklären, dass Ihre inneren Zellen enthält, und definieren die intrinsische Eigenschaft size so etwas wie dieses

class CustomAutoresizableView: UIView { 

    var subCells : [MenuTableCellContents 
] = []{ 
     didSet 
     { 
      ///Your code for add cells 
      self.invalidateIntrinsicContentSize() 
     } 
    } 

    override var intrinsicContentSize: CGSize 
    { 
     get 
     { 
      return CGSize(width: self.frame.width, height: CGFloat(self.arrayOfValues.count * 40)) 
     } 
    } 

} 

dann müssen Sie die richtigen Einschränkungen Ihre Hauptzelle liefern und stellen hohe Werte von Inhalten Kompressionswiderstand in vertikaler, verwende ich 1000 und danach müssen Sie diese zwei Zeilen in Ihrer MenuViewControllerviewDidLoad

self.menu_table.rowHeight = UITableViewAutomaticDimension 
    self.menu_table.estimatedRowHeight = 40 

in Ihrem cellForRowAtIndexPath y hinzufügen ou müssen diese durch diese EDIT


ersetzen

var subCells: [MenuTableCellContents] = [] {    
    willSet { 
     addSubCells() 
     self.invalidateIntrinsicContentSize() 
    } 
cell.yourCustomAutoresizableViewProperty.subCells = content.subCells 

if let subCells = content.subCells { 
     cell.subCells = subCells 
    } 

ersetzenMit diesem

var subCells: [MenuTableCellContents] = [] { 
    didSet{ 
     addSubCells() 
     self.invalidateIntrinsicContentSize() 
    } 
} 

Sie auch diese Methode müssen, bevor neue hinzufügen Zellen ausgeführt werden, weil Sie viele Zellen übereinander

func cleanSubViews() 
{ 
    for view in self.subviews { 
     view.removeFromSuperview() 
    } 
} 

hinzufügen Ich hoffe, das hilft Ihnen, wenn Sie irgendein Problem haben, mit Bitte lassen Sie mich wissen

+0

Ich fühle mich wie wir sind fast da. Ein Problem bleibt im Moment bestehen. Wenn ich es in 'willSet' oder' didSet' setze, werden die Ansichten neu gezeichnet, weil die Tabellenansicht funktioniert. Sie können sehen, dass es das tut. – NoSixties

+0

Sieht so aus, als würde es das nur im Simulator tun. Wenn ich es jedoch auf meinem Telefon starte, wird es nicht gezeichnet, bis die Zelle außerhalb der Ansicht ist. Ich werde ein Test-Projekt auf GitHub hochladen, so dass Sie sehen können, was ich meine – NoSixties

+0

Aktualisiert meine Post mit einem GitHub-Link – NoSixties

0

Als Ihre Frage wird nicht genügend Informationen zur Verfügung gestellt, aber ich werde es noch für eine Abstimmung geben.

Zuerst legen Sie die Beschriftungszeile 0 der Zelle und die Eigenschaft "word wrap" fest. Zweitens, versuchen Sie dies (Run und überprüfen Sie, ob es fertig ist, wenn nicht, dann folgen Sie unten Optionen auch).

nächsten Verwenden Sie die Funktion

label.intrinsicContentSize().height 

die Höhe des Textes auf dem Etikett erhalten dann stellen Sie die Höhe der Stadt und Zellhöhe berechnet durch Zugabe von anderen Räumen.

in Ihrem neuen Zellenhöhe zurückkehren unten Funktion

tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) 

Hope this können Sie Ihre Ausgabe erhalten.

Danke.

+0

Welche Informationen fehlen Ihnen? Das Etikett muss nicht in der Größe geändert werden. Die UIView muss skaliert werden (die schwarze Ansicht in den Screenshots). – NoSixties

Verwandte Themen