2017-11-28 8 views
1

Ich habe eine ViewController und ich möchte zwei 1 TableView und 1 ChildViewController drin haben.Mehrdeutiges Layout mit dynamischer TableView-Höhe

  • tableView ist mit dynamischen Zellenhöhen nicht scrollbar. (Ich verwende eine Tabelle, damit ich Zeilen reduzieren kann)
  • childVC ist eine scrollbare tableView mit dynamischen Zellenhöhen.

meine Zwänge wie:

NSLayoutConstraint.activate([ 
    tableView.topAnchor.constraint(equalTo: view.topAnchor), 
    tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 
    tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 
    tableView.bottomAnchor.constraint(equalTo: artistVC.view.topAnchor), 

]) 

NSLayoutConstraint.activate([ 
    artistVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), 
    artistVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), 
    artistVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) 
]) 

Wenn ich diese Einrichtung hat, nur der childVC auf dem Bildschirm zeigt. Ich sehe das TableView nicht. Ich möchte die TableView so viel erweitern, wie es benötigt und dann die ChildVC nach unten scrollen lassen.

  • für das Tableview I erhalten: Height and scrollable content size are ambiguous
  • für die Ansicht des childVC ich: Height and vertical positions are ambiguous

aber ich nicht die Höhe selbst festlegen kann, wie ich weiß nicht, was die Höhe der tableViewCell ist ..

Irgendwelche Vorschläge? Ich habe versucht, den inhaltlichen und inhaltlichen Druckwiderstand zu ändern, aber ich habe dort kein Glück gefunden.

Antwort

3

Ich schlage vor, Subklassifizieren UITableView wie folgt aus:

class AutomaticHeightTableView: UITableView { 

    override var intrinsicContentSize: CGSize { 
    return contentSize 
    } 

    override func reloadData() { 
    super.reloadData() 
    invalidateIntrinsicContentSize() 
    } 
} 

dann im Interface Builder gesetzt AutomaticHeightTableView als Klasse zu Ihrem Tabellenansicht und die Tabelle Größe selbst wird versuchen, den Inhalt zu passen. Es wird allen anderen Einschränkungen folgen, die Sie gesetzt haben, also stellen Sie sicher, dass die Einschränkungen es erlauben, frei zu wachsen.

+1

Nur eine Klarstellung für andere Leser: 'intrinsicContentSize' ist eine Eigenschaft von' UIView', die standardmäßig keine innere Größe hat, sondern nur '(0,0)' wäre. Dies würde dann "contentSize" als seinen neuen Wert geben. – Honey

+2

Auch über 'invalidateIntrinsicContentSize': Wenn Ihr TableView neu geladen werden muss, dann rufen Sie 'invalidateIntrinsicContentSize' auf, wenn Ihre Tabellenansicht Daten neu lädt * für die ** neue ** Inhaltsgröße – Honey

+0

' Erweiterung CollectionViewController: UICollectionViewDelegateFlowLayout * neu abfragt { func Kollektion (_ Collection: UICollectionView, Layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: indexPath) -> CGSize { wenn indexPath.row == 0 { wenn wir vc = data~~POS=TRUNC [indexPath.row] wie? ArtistDetailViewController { print ("detailVC ist \ (vc.tableView.intrinsicContentSize)") return vc.tableView.intrinsicContentSize } else { return CGSize (Breite: 10, Höhe: 10) } } ' – Honey

2

Tabellenansichten und andere scrollbare Ansichten haben keine intrinsicContentSize. Zum Beispiel wären Ihre Einschränkungen in Ordnung, wenn die teilnehmenden Ansichten eine UIImageView und eine UILabel sind, die beide nach ihrem Inhalt sortiert werden können, aber weil Ihre Ansichten eine UITableView und eine UIView sind (keine kann sich automatisch selbst bestimmen, obwohl Sie genug haben Einschränkungen auf der UIView, um nicht mehrdeutig zu sein) müssen Sie die Dimensionierung selbst vornehmen.

Um das gewünschte Verhalten zu erhalten, müssen Sie entweder die Unterklasse UITableView und überschreiben intrinsicContentSize oder Sie müssen eine Höhe Einschränkung setzen. In jedem Fall müssen Sie selbst die richtige Höhe berechnen. Content-Hugging und Kompressionswiderstand erlauben Auto-Layout zu entscheiden zwischen konkurrierenden intrinsicContentSizes und ist daher, warum sie in diesem Fall nicht helfen.

Zum Beispiel:

final class SizingTableView: UITableView { 
    override var intrinsicContentSize: CGSize { 
     return CGSize(width: bounds.width, height: <# Some appropriate height #>) 
    } 
} 

Dann in Ihrem Storyboard oder XIb die Klasse Ihrer Tabellenansicht SizingTableView ändern und Sie können für die intrinsische Inhalt Größe Ihrer Tabellenansicht in der Größe eine Entwurfszeit Platzhalter gesetzt inspizieren Sie, um eine Warnung vor unseren Fehlern zu beheben.

+1

Das Überschreiben von 'intrinsicContentSize' und das einfache Zurückgeben von' contentSize' sollte den Zweck erfüllen. Keine Notwendigkeit, etwas zu berechnen. – EmilioPelaez

+0

@EmilioPelaez umm meinen Sie hinzufügen 'Überschreibung var preferredContentSize: CGSize { get { self.tableView.layoutIfNeeded() return self.tableView.contentSize } Menge {} }' meinem Viewcontroller? Ich habe es von [hier] kopiert (https://stackoverflow.com/a/17939938/5175709). Und ich muss nichts anderes tun ?! – Honey

+1

'preferredContentSize' ist eine Eigenschaft von' UIViewController' 'intrinsicContentSize' ist eine Eigenschaft von' UIView'. Beim Autolayout wird 'intrinsicContentSize' verwendet, und Sie müssen es zurückgeben, um Mehrdeutigkeiten aufzulösen. Sie können möglicherweise tun, was andere vorschlagen, und "contentSize" zurückgeben, was eine Eigenschaft von "UIScrollView" ist. – beyowulf

Verwandte Themen