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

<p>можно ли изменить порядок таблицы. я много искал решение, но все результаты не совсем помогли достичь того, чего я пытаюсь достичь. все они предлагают прокрутить до последней позиции таблицы с помощью <code>scrolltorowatindexpath</code> и заполнить данные в обратном порядке. но это не работает, если содержимое таблицы является динамическим, и в некоторых случаях не все ячейки имеют данные. например, в обычном tableview порядок:</p><hr><h2>этикетка 1</h2><h2>ярлык 2</h2><h2>ярлык 3</h2><h2>пустой</h2><h2>пустой</h2><p>направление прокрутки<br/> v<br/> в<br/></p><hr><p>желаемый результат будет:<br/> направление прокрутки<br/> ^<br/> ^<br/></p><h2>пустой</h2><h2>пустой</h2><h2>пустой</h2><h2>ярлык 3</h2><h2>ярлык 2</h2><h2>этикетка 1</h2><hr><p>в этом примере, если бы я использовал предложенный метод <code>scrolltorowatindexpath</code> и использовал длину массива объектов, я бы получил только третью ячейку сверху. и в конечном итоге что-то вроде этого: </p><hr><p>нежелательный результат:</p><h2>ярлык 3</h2><h2>ярлык 2</h2><h2>этикетка 1</h2><h2>пустой</h2><h2>пустой</h2><p>направление прокрутки<br/> v<br/> в<br/></p><hr><p>любая помощь будет здорово, спасибо.</p>

<p>для заполнения таблицы<strong> снизу </strong>используйте это:</p><pre><code>- (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); } </code></pre><p>чтобы изменить порядок элементов, используйте это:</p><pre><code>datasourcearray = datasourcearray.reverseobjectenumerator.allobjects; </code></pre><p><strong> swift 2.2 </strong>версия (<strong> обновлена </strong>):</p><pre><code>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) } </code></pre><p><strong> swift 3.0 +/4.0 </strong>версия (<strong> обновлена </strong>):</p><pre><code>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) } </code></pre>

<p>первый обратный просмотр </p><pre><code> tableview.transform = cgaffinetransformmakescale (1,-1); </code></pre><p>затем обратная ячейка в ячейке создания.</p><pre><code>- (uitableviewcell*)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath; ... cell.contentview.transform = cgaffinetransformmakescale (1,-1); </code></pre>

<p>вот усовершенствованное решение решения klimczakm, которое работает с автоматически расположенными ячейками табличного представления (а также с фиксированными ячейками). это решение также работает с разделами, верхними и нижними колонтитулами.</p><p><strong> swift 3.0 </strong>:</p><pre class="lang-swift prettyprint-override"><code>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) } </code></pre><p><strong> нота: </strong></p><p>выше код не проверен, но должен работать ... просто убедитесь, что вы справитесь с высотой любой панели навигации или вкладки, и все будет в порядке. в приведенном выше коде я делаю это только для navbar!</p>

<p>простой способ - использовать несколько строк uilabel + autolayout . -> uitableview должен изменить его размер на основе содержимого (так называемый внутренний макет) . создайте табличное представление и установите следующий базовый класс:</p><pre><code>class intrinsictableview: uitableview { override var contentsize:cgsize { didset { self.invalidateintrinsiccontentsize() } } override var intrinsiccontentsize: cgsize { self.layoutifneeded() return cgsize(width: uiviewnointrinsicmetric, height: contentsize.height) } </code></pre><p>}</p><p>теперь установите левое, правое и нижнее ограничения макета для вашего вывода таблицы, чтобы оно было родительским представлением наиболее важным является ограничение верхнего макета, которое должно быть больше или равно 0. это условие гарантировано, что таблица не будет выше родительского представления. </p>

<p>swift 3.01 - другое решение можно повернуть и перевернуть tableview.</p><pre><code>self.tableview.transform = cgaffinetransform.init(rotationangle: (-(cgfloat)(m\_pi))) self.tableview.transform = cgaffinetransform.init(translationx: -view.frame.width, y: view.frame.height) </code></pre><p> <a href="https://stackoverflow.com/questions/5679835/uitableview-anchor-rows-to-bottom/41253989#41253989">uitableview привязать строки к низу</a> </p>

<p>не пытайтесь написать код самостоятельно .. почему бы вам не использовать reverseextension. это очень просто и даст вам все необходимые результаты. пожалуйста, следуйте этому url <a href="https://github.com/marty-suzuki/reverseextension">https://github.com/marty-suzuki/reverseextension</a> </p><p><strong>примечание:</strong> всякий раз, когда вам нужно добавить новую ячейку, вставьте новую добавленную модель в нулевой индекс массива источника данных, чтобы новая ячейка добавлялась снизу. в противном случае это добавит ячейку сверху, и вы снова запутаетесь.</p>

<p>я сделал в методе cellforrowat:</p><pre><code>let reverseindex = myarray.count-indexpath.row-1 let currcelldata = myarray.object(at: reverseindex) </code></pre><p>а затем вы продолжаете работать с currcelldata</p>

<p>это решение корректирует вставку содержимого<strong> при изменении размера содержимого </strong>с использованием kvo. он также учитывает вставку содержимого при прокрутке до верхней части, так как простая прокрутка до <code>cgpointzero</code> будет прокручивать до верхней части содержимого вместо прокрутки до верхней части таблицы.</p><pre><code>-(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]; } } </code></pre>