Подтвердить что ты не робот

Как заполнить UITableView снизу вверх?

Можно ли отменить порядок tableView. Я много искал решение, но все результаты не совсем были решением того, чего я пытаюсь достичь. Все они предлагают прокрутку до последней позиции таблицы с scrollToRowAtIndexPath и заполнение данных в обратном порядке. Но это не работает, если содержимое таблицы является динамическим, а в некоторых случаях не все ячейки имеют данные. Например, в обычном tableView порядок:


label 1

метка 2

метка 3

пусто

пусто

направление прокрутки
v
В


желаемый результат:
направление прокрутки
^
^

пусто

пусто

пусто

метка 3

метка 2

label 1


в этом примере, если я использовал предложенный метод scrollToRowAtIndexPath и использовал длину массива объектов, я бы получил только третью ячейку сверху. И в итоге получилось что-то вроде этого:


нежелательный результат:

метка 3

метка 2

label 1

пусто

пусто

направление прокрутки
v
В


любая помощь будет большой благодарностью.

4b9b3361

Ответ 1

Чтобы заполнить таблицу снизу, используйте это:

- (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);
}

Чтобы изменить порядок элементов, используйте это:

dataSourceArray = dataSourceArray.reverseObjectEnumerator.allObjects;

Swift 4.2/5 версия:

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 = UIEdgeInsets(top: contentInsetTop,left: 0,bottom: 0,right: 0)
}

Swift 3/4.0 версия:

self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0)

Ответ 2

первый обратный просмотр

    tableView.transform = CGAffineTransformMakeScale (1,-1);

затем обратная ячейка в ячейке создания.

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

    ...

    cell.contentView.transform = CGAffineTransformMakeScale (1,-1);

Ответ 3

Swift 4.0 и 4.2 версия

Первый обратный UITableView в viewDidLoad

override func viewDidLoad() {
        super.viewDidLoad()
        tableView.transform = CGAffineTransform(scaleX: 1, y: -1)
}

Затем переверните ячейку в cellForRowAt.

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
    }

Ответ 4

Вот уточненное решение KlimczakM, которое работает с автозавершенными ячейками таблицы (а также фиксированными). Это решение также работает с разделами, заголовками разделов и нижними колонтитулами раздела.

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

Примечание:

Выше код не проверен, но должен работать. Просто убедитесь, что вы справляетесь с высотой любой навигационной панели или панели, и все будет хорошо. В приведенном выше коде я делаю это только для навигатора!

Ответ 5

Не надо писать код самостоятельно. Почему бы вам не использовать ReverseExtension. Это очень просто и даст вам все необходимые результаты. Пожалуйста, следуйте по этому адресу https://github.com/marty-suzuki/ReverseExtension

Примечание: всякий раз, когда вам нужно добавить новую ячейку, пожалуйста, вставьте новую добавленную модель в нулевой индекс массива источника данных, чтобы новая ячейка добавлялась снизу. В противном случае это добавит ячейку сверху, и вы снова запутаетесь.

Ответ 6

Простой способ - использовать несколько строк UILabel + autolayout. → UITableView должен изменить размер, основываясь на его содержимом (так называемый внутренний макет). Создайте свое табличное представление и установите следующий базовый класс:

class IntrinsicTableView: UITableView {

override var contentSize:CGSize {
    didSet {
        self.invalidateIntrinsicContentSize()
    }
}

override var intrinsicContentSize: CGSize {
    self.layoutIfNeeded()
    return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
}

}

Теперь установите левые, правые и нижние ограничения макета для вашего вывода таблицы, чтобы это было родительское представление. Наиболее важным является ограничение верхнего макета, которое должно быть больше или равно 0. Это условие гарантирует, что таблица не будет выше родительского представления.

Ответ 7

Swift 3.01 - Другое решение может быть, поворачивать и переворачивать таблицуView.

self.tableView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(M_PI)))
self.tableView.transform = CGAffineTransform.init(translationX: -view.frame.width, y: view.frame.height)

Строки привязки UITableView снизу

Ответ 8

Я использовал метод cellForRowAt:

let reverseIndex = myArray.count-indexPath.row-1

let currCellData = myArray.object(at: reverseIndex) 

а затем вы продолжите работу с currCellData​​p >

Ответ 9

Это решение отрегулирует вложенный контент с изменением размера содержимого с помощью KVO. Он также учитывает вставку содержимого при прокрутке вверх, поскольку простая прокрутка до CGPointZero будет прокручиваться до верхней части содержимого, а не прокручиваться до верхней части таблицы.

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

    }
}

Ответ 10

Если у вас есть массив объектов, которые вы показываете в cellForRowAtIndexPath:, скажем dataArray, вы можете отменить его или в cellForRowAtIndexPath: вы можете сделать что-то подобное:

NSString *yourObject = dataArray[[dataArray count] - 1 - indexPath.row];
cell.textLabel.text = yourObject

Я предполагаю, что вы сохраняете строки в dataArray.