it-swarm.com.de

Wie befüllt man UITableView von unten nach oben?

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:


label 1

etikett 2

label 3

leeren

leeren

richtung scrollen
v
V


das gewünschte Ergebnis wäre:
Scrollrichtung
^
^

leeren

leeren

leeren

label 3

etikett 2

label 1


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:

label 3

etikett 2

label 1

leeren

leeren

richtung scrollen
v
V


jede Hilfe wäre super danke.

26
kai Taylor

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)
}
24
KlimczakM

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);
6
waynett

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
    }
5
Akbar Khan

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!

3
Alexander W

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. 

2
Trung Phan

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)

UITableView Ankerzeilen nach unten

1
Maximo Lucosi

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.

1

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

0
Gulz

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];

    }
}
0
Eran Goldin