ist es möglich, die Reihenfolge einer tableView umzukehren. Ich habe viel nach einer Lösung gesucht, aber nicht alle Ergebnisse waren eine Lösung für das, was ich erreichen möchte. Sie alle schlagen vor, mit scrollToRowAtIndexPath
an die letzte Position einer Tabelle zu scrollen und die Daten in umgekehrter Reihenfolge zu füllen. Dies funktioniert jedoch nicht, wenn der Tabelleninhalt dynamisch ist und in einigen Fällen nicht alle Zellen Daten enthalten. In einer normalen tableView lautet die Reihenfolge beispielsweise:
richtung scrollen
v
V
das gewünschte Ergebnis wäre:
Scrollrichtung
^
^
wenn ich in diesem Beispiel die vorgeschlagene Methode von scrollToRowAtIndexPath
und die Länge des Arrays von Objekten verwendet, würde ich nur die dritte Zelle von oben erhalten. Und am Ende so etwas:
unerwünschtes Ergebnis:
richtung scrollen
v
V
jede Hilfe wäre super danke.
Um die Tabelle von unten zu befüllen verwenden Sie diese:
- (void)updateTableContentInset {
NSInteger numRows = [self tableView:self.tableView numberOfRowsInSection:0];
CGFloat contentInsetTop = self.tableView.bounds.size.height;
for (NSInteger i = 0; i < numRows; i++) {
contentInsetTop -= [self tableView:self.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
if (contentInsetTop <= 0) {
contentInsetTop = 0;
break;
}
}
self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0);
}
Um die Reihenfolge der Elemente umzukehren, verwenden Sie Folgendes:
dataSourceArray = dataSourceArray.reverseObjectEnumerator.allObjects;
Swift 2.2 version ( aktualisiert ):
func updateTableContentInset() {
let numRows = tableView(self.tableView, numberOfRowsInSection: 0)
var contentInsetTop = self.tableView.bounds.size.height
for i in 0..<numRows {
let rowRect = self.tableView.rectForRowAtIndexPath(NSIndexPath(forItem: i, inSection: 0))
contentInsetTop -= rowRect.size.height
if contentInsetTop <= 0 {
contentInsetTop = 0
}
}
self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0)
}
Swift 3.0 +/4.0 version ( aktualisiert ):
func updateTableContentInset() {
let numRows = tableView(self.tableView, numberOfRowsInSection: 0)
var contentInsetTop = self.tableView.bounds.size.height
for i in 0..<numRows {
let rowRect = self.tableView.rectForRow(at: IndexPath(item: i, section: 0))
contentInsetTop -= rowRect.size.height
if contentInsetTop <= 0 {
contentInsetTop = 0
}
}
self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0)
}
erste umkehrbare Ansicht
tableView.transform = CGAffineTransformMakeScale (1,-1);
dann umkehren Zelle in Zelle erstellen.
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
...
cell.contentView.transform = CGAffineTransformMakeScale (1,-1);
Swift 4.0 und 4.2 Version
Zuerst kehren Sie UITableView in viewDidLoad um
override func viewDidLoad() {
super.viewDidLoad()
tableView.transform = CGAffineTransform(scaleX: 1, y: -1)
}
Kehren Sie dann die Zelle in cellForRowAt um.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath) as? MyTableViewCell else { fatalError() }
cell.contentView.transform = CGAffineTransform(scaleX: 1, y: -1)
return cell
}
Hier ist eine weiterentwickelte Lösung der KlimczakM-Lösung, die mit automatisch ausgerichteten Tableview-Zellen (sowie den festen) arbeitet. Diese Lösung funktioniert auch mit Abschnitten, Abschnittskopfzeilen und Abschnittsfußzeilen.
Swift 3.0 :
func updateTableContentInset(forTableView tv: UITableView) {
let numSections = tv.numberOfSections
var contentInsetTop = tv.bounds.size.height -
(self.navigationBar?.frame.size.height ?? 0)
for section in 0..<numSections {
let numRows = tv.numberOfRows(inSection: section)
let sectionHeaderHeight = tv.rectForHeader(inSection: section).size.height
let sectionFooterHeight = tv.rectForFooter(inSection: section).size.height
contentInsetTop -= sectionHeaderHeight + sectionFooterHeight
for i in 0..<numRows {
let rowHeight = tv.rectForRow(at: IndexPath(item: i, section: section)).size.height
contentInsetTop -= rowHeight
if contentInsetTop <= 0 {
contentInsetTop = 0
break
}
}
// Break outer loop as well if contentInsetTop == 0
if contentInsetTop == 0 {
break
}
}
tv.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0)
}
HINWEIS:
Der obige Code ist nicht getestet, sollte aber funktionieren. Stellen Sie einfach sicher, dass Sie die Höhe einer Navbar oder Tabbar beherrschen, und Sie werden in Ordnung sein. Im obigen Code mache ich das nur für die Navbar!
Die einfache Methode ist die Verwendung von UILabel mit mehreren Zeilen + autolayout .->. UITableView sollte die Größe des Inhalts basierend auf dessen Inhalt (auch als intrinsisches Layout bezeichnet) festlegen.
class IntrinsicTableView: UITableView {
override var contentSize:CGSize {
didSet {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
self.layoutIfNeeded()
return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
}
}
Setzen Sie nun die linken und unteren Layouteinschränkungen für Ihre Tableview-Pin auf die übergeordnete Ansicht. Die wichtigste ist, dass die obere Layouteinschränkung auf einen Wert von 0 oder größer 0 gesetzt wird.
Swift 3.01 - Eine andere Lösung kann das tableView sein, drehen und drehen.
self.tableView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(M_PI)))
self.tableView.transform = CGAffineTransform.init(translationX: -view.frame.width, y: view.frame.height)
Machen Sie sich nicht die Mühe, den Code selbst zu schreiben. Warum verwenden Sie nicht ReverseExtension? Es ist sehr einfach und liefert Ihnen alle erforderlichen Ergebnisse. Bitte folgen Sie dieser url https://github.com/marty-suzuki/ReverseExtension
Note: Wenn Sie eine neue Zelle hinzufügen müssen, fügen Sie das neu hinzugefügte Modell am nullten Index des Datenquellenarrays ein, sodass die neue Zelle unten hinzugefügt wird. Andernfalls würde die Zelle oben hinzugefügt, und Sie werden erneut verwirrt.
Ich habe in der cellForRowAt-Methode gemacht:
let reverseIndex = myArray.count-indexPath.row-1
let currCellData = myArray.object(at: reverseIndex)
und dann arbeiten Sie weiter mit currCellData
Diese Lösung passt den Inhalt des Inhalts bei Änderung der Inhaltsgröße mithilfe von KVO an. Es berücksichtigt auch den Inhaltseinsatz, wenn Sie nach oben scrollen, da einfach nach CGPointZero
geblättert wird, um an den Anfang des Inhalts zu blättern, anstatt an den Anfang der Tabelle zu scrollen.
-(void)startObservingContentSizeChanges
{
[self.tableView addObserver:self forKeyPath:kKeyPathContentSize options:0 context:nil];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:kKeyPathContentSize] && object == self.tableView)
{
// difference between content and table heights. +1 accounts for last row separator
CGFloat height = MAX(self.tableView.frame.size.height - self.tableView.contentSize.height, 0) + 1;
self.tableView.contentInset = UIEdgeInsetsMake(height, 0, 0, 0);
// "scroll" to top taking inset into account
[self.tableView setContentOffset:CGPointMake(0, -height) animated:NO];
}
}