菜鸟教程小白 发表于 2022-12-13 09:52:30

ios - 将 TableView 与许多自定义单元格和自动布局一起使用


                                            <p><p>我想重构一些代码以获得更好的性能,但我的问题是我不知道该怎么做。目前我有一个 <code>UIViewController</code> 上面有一个 <code>UIScrollView</code>。</p>

<p>我还有 20 个不同的 View (每个都有它的 .h 和 .m 文件)可以完全动态地放置在我的 <code>UIScrollView</code> 上。每次我启动 <code>UIViewController</code> 时,我都会向我的服务器发送一个请求,然后我得到响应,然后我知道我必须在 <code>UIScrollView</code> 上放置多少 View 。
所以你可以想象,当我的 <code>UIScrollView</code> 上有很多不同的 View 时,需要几秒钟,因为所有 View 都已完全加载,然后用户才能最终与它们交互。</p>

<p>所以我的想法是用 <code>UITableView</code> 替换 <code>UIScrollView</code> 并将所有 CustomViews (<code>UIViews</code>) 更改为自定义 <code>UITableViewCells</code>。所以第一次启动时只会加载可见的单元格!</p>

<p>知道我有几个问题。</p>

<ol>
<li><p>目前,我的 CustomViews 中的大部分代码都是使用 <code>Frames</code> 构建的,但我想将其完全更改为 <code>Autolayout</code>,我不认为用 <code>IB</code> (xib 文件...)构建它们是有意义的。所以我必须在代码中完成整个自动布局?</p></li>
<li><p>有些自定义 View 非常大,所以它们变得非常高,而有些可能非常小。我担心的是滚动性能会非常糟糕......因为我不能真正使用 <code>estimatedRowHeight</code>(一个例子:有时一个单元格可以获得 1000.0f 的高度,而下一个单元格只有 40.0f)。结合自动布局和我必须等到来 self 的服务器的响应到达的时间,我认为这对用户来说真的很烦人。</p></li>
<li><p>最多可以有 20 种不同!自定义行,在这种情况下使用 <code>UITableView</code> 真的有意义吗?正如我之前提到的,它们的大小和内容都非常不同!</p></li>
</ol>

<p>这是我的新代码的一小部分:</p>

<pre><code>- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return ;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GTBlockView *cell = ;


GFBlock *block = ;

//createInterfaceforBlock -- Here the Cell gets called and the Content and the Size gets defined
cell = [createInterfaceForBlock:block];

// Make sure the constraints have been added to this cell, since it may have just been created from scratch
;
;

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

//GTBlockView is the SuperView of all my Custom Cells
GTBlockView *cell = ;

if (!cell)
{
    cell = [ init];

    ;
}

GFBlock *block = ;

//createInterfaceforBlock -- Here the Cell gets called and the Content and the Size gets defined
cell = [ createInterfaceForBlock:block];

// Make sure the constraints have been added to this cell, since it may have just been created from scratch
;
;


cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

;
;

// Get the actual height required for the cell
CGFloat height = .height;


height += 1;


return height;
}
</code></pre>

<p>也许你们中的一些人有一些更好的想法或一些好的来源?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我已经完全按照您在我自己的应用程序中的想法做了 - 我首先沿着 UIScrollview 路线走,然后我改为使用多种自定义单元格的 UITableview。它确实完全有意义并且非常值得 - 我从 uitableview 获得了巨大的性能提升。 UIScrollview 的主要问题之一是它会为你的 contentView 中的所有内容计算出自动布局,正如你所说,这可能需要几秒钟,但 UITableview 会更快更有效地处理这个问题。所以 - 去吧。</p>

<p>我强烈建议您为每个自定义单元格使用唯一的 XIB 文件。分别在每一个中进行自动布局,这样你就更有可能避免出现问题。编程约束更难维护,而且自动布局通常具有挑战性。</p>

<p>为了让这一切正常工作,我做了以下事情:首先我有一个 UITableviewCell 的子类,它是所有其他单元格对象的父类。在我的例子中,这被称为 SNFormTableCell (UITableviewCell)。然后所有其他单元格对象都基于这个类。在我的 cellForRowAtIndexPath 方法中,我这样做:</p>

<pre><code>ReportItem *objectForCell = ; //my personal data class - just contains the cell data I need
NSString *identifier = ;
SNFormTableCell *cell = ;
if (!cell)
{
    forCellReuseIdentifier:identifier];
    cell = ;
    cell.contentView.clipsToBounds = YES;
}
;//i have a delegate that calls back to the tableview when cells are interacted with
cell.reportItem = objectForCell; //put the data object onto the cell to do with as the cell requires
;//update the UI using the data - this is over-ridden by the various subclasses of the cell
</code></pre>

<p>其中的方法称为 <code>getNibNameAndReusableIdentifierNameForObjectType</code> .. 看起来像这样(只是获取我们需要的 nib 和重复使用的标识符):</p>

<pre><code>- (NSString*) getNibNameAndReusableIdentifierNameForObjectType:(SNFormTableObjectType)objectType {
if (objectType == SNFormTableObjectTypeBoolean) return @&#34;SNBooleanCell&#34;;
if (objectType == SNFormTableObjectTypeDatePicker) return @&#34;SNDatePickerCell&#34;;
if (objectType == SNFormTableObjectTypeDropDown) return @&#34;SNDropDownCell&#34;;
if (objectType == SNFormTableObjectTypeDropDownPlusSingleLineText) return @&#34;SNDropDownPlusSingleLineTextCell&#34;;
... etc
}
</code></pre>

<p>最后,父单元类有一个名为-(void) refreshUI的方法。所以我把数据对象放到那个单元格上——这包含了单元格可能需要的所有数据。子类以自己特定的方式覆盖此 refreshUI 方法,以根据需要使用数据。</p>

<p>只是重申一下,我从这条路线上获得了巨大的 yield 。包含大量内容的 ScrollView ,需要 5 秒或更长时间来加载 nib 并计算自动布局(也在主线程上,使应用程序无响应),会立即出现在 UITableview 版本上。所以去吧。如果您需要有关如何进行的更多详细信息,请告诉我。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 将 TableView 与许多自定义单元格和自动布局一起使用,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/32050317/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/32050317/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 将 TableView 与许多自定义单元格和自动布局一起使用