UITableView灵活/动态heightForRowAtIndexPath [英] UITableView flexible/dynamic heightForRowAtIndexPath

查看:76
本文介绍了UITableView灵活/动态heightForRowAtIndexPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常你会使用 cellForRowAtIndexPath 委托方法来设置你的单元格。为单元格设置的信息对于单元格的绘制方式以及大小的大小非常重要。

Normally you would use the cellForRowAtIndexPath delegate method to setup your cell. The information set for the cell is important for how the cell is drawn and what the size will be.

不幸的是 heightForRowAtIndexPath 委托方法在 cellForRowAtIndexPath 委托方法之前调用,因此我们不能简单地告诉委托返回单元格的高度,因为那时它将为零。

Unfortunatly the heightForRowAtIndexPath delegate method is called before the cellForRowAtIndexPath delegate method so we can't simply tell the delegate to return the height of the cell, since this will be zero at that time.

因此我们需要在表格中绘制单元格之前计算大小。幸运的是,有一种方法可以实现, sizeWithFont ,属于NSString类。然而,存在问题,为了动态地计算正确的大小,它需要知道如何呈现单元中的元素。我将在一个示例中明确说明:

So we need to calculate the size before the cell is drawn in the table. Luckily there is a method that does just that, sizeWithFont, which belongs to the NSString class. However there is problem, in order to calculate the correct size dynamically it needs to know how the elements in the cell will be presented. I will make this clear in an example:

想象一下 UITableViewCell ,其中包含一个名为<$ c $的标签C>为textLabel 。在 cellForRowAtIndexPath 委托方法中,我们放置 textLabel.numberOfLines = 0 ,它基本上告诉标签它可以有多少行因为它需要呈现特定宽度的文本。如果我们给textLabel一个大于最初赋予textLabel的宽度的文本,就会出现问题。第二行将出现,但单元格的高度不会自动调整,因此我们得到一个混乱的查看表视图。

Imagine a UITableViewCell, which contains a label named textLabel. Within the cellForRowAtIndexPath delegate method we place textLabel.numberOfLines = 0, which basically tells the label it can have as many lines as it needs to present the text for a specific width. The problem occurs if we give textLabel a text larger then the width originally given to textLabel. The second line will appear, but the height of the cell will not be automatically adjusted and so we get a messed up looking table view.

如前所述,我们可以使用 sizeWithFont 计算高度,但需要知道使用哪个Font,宽度等等。如果为了简单起见,我们只关心宽度,我们可以硬编码,宽度约为320.0(不考虑填充)。但是如果我们使用UITableViewStyleGrouped而不是普通宽度那么将会发生大约300.0并且单元格将再次混乱。或者如果我们从纵向交换到横向,发生了什么,我们有更多的空间,但由于我们硬编码300.0,它将不会被使用。

As said earlier, we can use sizeWithFont to calculate the height, but it needs to know which Font is used, for what width, etc. If, for simplicity reasons, we just care about the width, we could hardcode that the width would be around 320.0 (not taking padding in consideration). But what would happen if we used UITableViewStyleGrouped instead of plain the width would then be around 300.0 and the cell would again be messed up. Or what happends if we swap from portrait to landscape, we have much more space, yet it won't be used since we hardcoded 300.0.

这是这样的情况在某些时候你必须问自己一个问题,你可以避免多少硬编码。

This is the case in which at some point you have to ask yourself the question how much can you avoid hardcoding.

您可以调用属于UITableView类的 cellForRowAtIndexPath 方法来获取特定部分和行的单元格。我读了几篇帖子说你不想那样做,但我真的不明白。是的,我同意它已经分配了单元格,但 heightForRowAtIndexPath 委托方法仅针对将可见的单元格调用,因此无论如何都将分配单元格。如果正确使用 dequeueReusableCellWithIdentifier ,则不会在 cellForRowAtIndexPath 方法中再次分配单元格,而是使用指针属性只是调整。那有什么问题呢?

You could call the cellForRowAtIndexPath method that belongs to the UITableView class to get the cell for a certain section and row. I read a couple of posts that said you don't want to do that, but I don't really understand that. Yes, I agree it will already allocate the cell, but the heightForRowAtIndexPath delegate method is only called for the cells that will be visible so the cell will be allocated anyway. If you properly use the dequeueReusableCellWithIdentifier the cell will not be allocated again in the cellForRowAtIndexPath method, instead a pointer is used and the properties are just adjusted. Then what's the problem?

请注意,当表格视图单元格变为可见脚本时,单元格不会在 cellForRowAtIndexPath 委托方法中绘制将在UITableVieCell上调用 setNeedDisplay 方法,该方法触发 drawRect 方法来绘制单元格。所以直接调用 cellForRowAtIndexPath 委托不会失去性能,因为它需要被绘制两次。

Note that the cell is NOT drawn within the cellForRowAtIndexPath delegate method, when the table view cell becomes visible the script will call the setNeedDisplay method on the UITableVieCell which triggers the drawRect method to draw the cell. So calling the cellForRowAtIndexPath delegate directly will not lose performance because it needs to be drawn twice.

好的,所以通过调用在 heightForRowAtIndexPath 委托方法中的 cellForRowAtIndexPath 委托方法,我们会收到有关单元格所需的所有信息,以确定它的大小。

Okay so by calling the cellForRowAtIndexPath delegate method within the heightForRowAtIndexPath delegate method we receive all the information we need about the cell to determine it's size.

也许你可以创建自己的 sizeForCell 方法来运行所有选项,如果单元格在Value1中,该怎么办?风格,或Value2等。

Perhaps you can create your own sizeForCell method that runs through all the options, what if the cell is in Value1 style, or Value2, etc.

这只是我在思想中描述的理论,我想知道我写的是否正确。或者也许还有另一种方法来完成同样的事情。请注意,我希望能够尽可能灵活地做事。

It's just a theory I described in my thoughts, I would like to know if what I wrote is correct. Or that maybe there is another way to accomplish the same thing. Note that I want to be able to do things as flexible as possible.

推荐答案


是的,我同意它已经分配了单元格,但是仅为可见的单元格调用heightForRowAtIndexPath委托方法,因此无论如何都将分配单元格。

Yes, I agree it will already allocate the cell, but the heightForRowAtIndexPath delegate method is only called for the cells that will be visible so the cell will be allocated anyway.

这是不正确的。表视图需要为表视图中的所有行调用 heightForRowAtIndexPath (如果已实现),而不仅仅是当前显示的行。原因是它需要计算出它的总高度才能显示正确的滚动指示器。

This is incorrect. The table view needs to call heightForRowAtIndexPath (if it's implemented) for all rows that are in the table view, not just the ones currently being displayed. The reason is that it needs to figure out its total height to display the correct scroll indicators.

这篇关于UITableView灵活/动态heightForRowAtIndexPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆