Ich habe in den letzten 3 oder 4 Stunden meinen Kopf gegen die Wand geschlagen und ich kann es scheinbar nicht herausfinden. Ich habe einen UIViewController mit einer UITableView im Vollbildmodus (es gibt einige andere Dinge auf dem Bildschirm, weshalb ich keinen UITableViewController verwenden kann) und ich möchte, dass meine tableHeaderView die Größe mit Autolayout ändert. Unnötig zu sagen, dass es nicht kooperiert.
Siehe Screenshot unten.
Da das Übersichtslabel (z. B. der Text "Übersichtsinformationen hier auflisten") dynamischen Inhalt hat, verwende ich das automatische Layout, um die Größe zu ändern und die Übersicht anzuzeigen. Ich habe alles schön in der Größe geändert, außer der tableHeaderView, die sich direkt unter Paralax Table View in der Hiearchy befindet.
Die einzige Möglichkeit, die Größe dieser Header-Ansicht zu ändern, ist programmgesteuert mit dem folgenden Code:
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = headerFrameHeight;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];
In diesem Fall ist headerFrameHeight eine manuelle Berechnung der tableViewHeader-Höhe wie folgt (innerHeaderView ist der weiße Bereich oder die zweite "Ansicht", headerView ist tableHeaderView) :
CGFloat startingY = self.innerHeaderView.frame.origin.y + self.overviewLabel.frame.origin.y;
CGRect overviewSize = [self.overviewLabel.text
boundingRectWithSize:CGSizeMake(290.f, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName: self.overviewLabel.font}
context:nil];
CGFloat overviewHeight = overviewSize.size.height;
CGFloat overviewPadding = ([self.overviewLabel.text length] > 0) ? 10 : 0; // If there's no overviewText, eliminate the padding in the overall height.
CGFloat headerFrameHeight = ceilf(startingY + overviewHeight + overviewPadding + 21.f + 10.f);
Die manuelle Berechnung funktioniert, ist jedoch umständlich und fehleranfällig, wenn sich die Dinge in Zukunft ändern. Ich möchte in der Lage sein, die Größe von tableHeaderView basierend auf den bereitgestellten Einschränkungen automatisch zu ändern, wie Sie es überall tun können. Aber für mein Leben kann ich es nicht herausfinden.
Es gibt mehrere Beiträge zu SO darüber, aber keiner ist klar und hat mich mehr verwirrt. Hier sind einige:
Es ist nicht wirklich sinnvoll, die Eigenschaft translatesAutoresizingMaskIntoConstraints in NO zu ändern, da dies nur Fehler für mich verursacht und konzeptionell sowieso keinen Sinn ergibt.
Jede Hilfe wäre wirklich dankbar!
EDIT 1: Dank TomSwifts Vorschlag konnte ich es herausfinden. Anstatt die Höhe der Übersicht manuell zu berechnen, kann ich sie wie folgt für mich berechnen lassen und dann die tableHeaderView wie zuvor zurücksetzen.
[self.headerView setNeedsLayout];
[self.headerView layoutIfNeeded];
CGFloat height = [self.innerHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + self.innerHeaderView.frame.origin.y; // adding the origin because innerHeaderView starts partway down headerView.
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = height;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];
Bearbeiten 2: Wie andere angemerkt haben, scheint die in Bearbeiten 1 veröffentlichte Lösung in viewDidLoad nicht zu funktionieren. Es scheint jedoch in viewWillLayoutSubviews zu funktionieren. Beispielcode unten:
// Note 1: The variable names below don't match the variables above - this is intended to be a simplified "final" answer.
// Note 2: _headerView was previously assigned to tableViewHeader (in loadView in my case since I now do everything programatically).
// Note 3: autoLayout code can be setup programatically in updateViewConstraints.
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[_headerWrapper setNeedsLayout];
[_headerWrapper layoutIfNeeded];
CGFloat height = [_headerWrapper systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect headerFrame = _headerWrapper.frame;
headerFrame.size.height = height;
_headerWrapper.frame = headerFrame;
_tableView.tableHeaderView = _headerWrapper;
}
quelle
setTableHeaderView
funktioniert nicht auf Xcode6. Das Problem ist, dass sich Zellen von tableHeaderView überlappen. Es funktioniert jedoch auf Xcode5Antworten:
Sie müssen die
UIView systemLayoutSizeFittingSize:
Methode verwenden, um die minimale Begrenzungsgröße Ihrer Header-Ansicht zu erhalten.Ich biete weitere Diskussionen zur Verwendung dieser API in dieser Frage / Antwort:
Wie kann ich die Größe der Übersicht ändern, um sie an alle Unteransichten mit Autolayout anzupassen?
quelle
Ich habe wirklich mit diesem gekämpft und das Einfügen des Setups in viewDidLoad hat bei mir nicht funktioniert, da der Frame nicht in viewDidLoad festgelegt ist. Außerdem gab es unzählige unordentliche Warnungen, bei denen die gekapselte Höhe des automatischen Layouts des Headers auf 0 reduziert wurde Ich habe das Problem auf dem iPad nur beim Präsentieren einer tableView in einer Formularpräsentation bemerkt.
Was das Problem für mich löste, war das Festlegen des tableViewHeader in viewWillLayoutSubviews und nicht in viewDidLoad.
quelle
Ich habe einen eleganten Weg gefunden, das automatische Layout zum Ändern der Größe von Tabellenüberschriften mit und ohne Animation zu verwenden.
Fügen Sie dies einfach Ihrem View Controller hinzu.
So ändern Sie die Größe entsprechend einer sich dynamisch ändernden Bezeichnung:
So animieren Sie eine Größenänderung gemäß einer Änderung einer Einschränkung:
Sehen Sie sich das AutoResizingHeader-Projekt an, um dies in Aktion zu sehen. https://github.com/p-sun/Swift2-iOS9-UI
quelle
@IBOutlet makeThisTaller
und das Sie@IBAction fun makeThisTaller
im Beispiel mögen. Beschränken Sie außerdem alle Seiten Ihres Etiketts auf den tableViewHeader (z. B. oben, unten, links und rechts).lblFeedDescription.preferredMaxLayoutWidth = lblFeedDescription.bounds.width
wobei das Etikett dasjenige ist, das ich vergrößern möchte. Vielen Dank !Ihre Lösung mit systemLayoutSizeFittingSize: funktioniert, wenn die Kopfzeilenansicht bei jedem Erscheinungsbild nur einmal aktualisiert wird. In meinem Fall wurde die Header-Ansicht mehrmals aktualisiert, um Statusänderungen widerzuspiegeln. Aber systemLayoutSizeFittingSize: hat immer die gleiche Größe gemeldet. Das heißt, die Größe, die dem ersten Update entspricht.
Um systemLayoutSizeFittingSize zu erhalten: Um nach jedem Update die richtige Größe zurückzugeben, musste ich zuerst die Tabellenkopfansicht entfernen, bevor ich sie aktualisierte und erneut hinzufügte:
quelle
Diese Lösung ändert die Größe von tableHeaderView und vermeidet Endlosschleifen in der
viewDidLayoutSubviews()
Methode, die ich mit einigen der anderen Antworten hier hatte:Siehe auch diesen Beitrag: https://stackoverflow.com/a/34689293/1245231
quelle
Dies funktionierte bei mir auf ios10 und Xcode 8
quelle
Es funktioniert sowohl für die Kopf- als auch für die Fußzeile. Ersetzen Sie einfach die Kopfzeile durch die Fußzeile
quelle
Unter iOS 12 und höher stellen die folgenden Schritte sicher, dass das automatische Layout sowohl in Ihrer Tabelle als auch im Header ordnungsgemäß funktioniert.
quelle
In meinem Fall
viewDidLayoutSubviews
hat es besser funktioniert.viewWillLayoutSubviews
bewirkt, dass weiße Linien von atableView
erscheinen. Außerdem habe ich die Überprüfung hinzugefügt, ob meinheaderView
Objekt bereits vorhanden ist.quelle
Es ist durchaus möglich, generisches AutoLayout-basiertes
UIView
mit jeder inneren AL-Unteransichtsstruktur als zu verwendentableHeaderView
.Das einzige, was man braucht, ist ein einfaches
tableFooterView
vorher einzustellen !Let
self.headerView
basiert auf EinschränkungenUIView
.Wenn
self.headerView
sich die Höhe unter UI-Rotation ändert, muss dies implementiert werdenZu diesem Zweck kann die ObjC- Kategorie verwendet werden
Und auch Swift- Erweiterung
quelle
Diese Lösung funktioniert perfekt für mich:
https://spin.atomicobject.com/2017/08/11/swift-extending-uitableviewcontroller/
Es erweitert den UITableViewController. Wenn Sie jedoch nur eine UITableView verwenden, funktioniert dies weiterhin. Erweitern Sie einfach die UITableView anstelle des UITableViewController. Rufen Sie die Methoden auf
sizeHeaderToFit()
odersizeFooterToFit()
wann immer es ein Ereignis gibt, das dietableViewHeader
Höhe ändert .quelle