为什么空的 tableView 会检查部分的数量,而非空的则不会? [英] Why does an empty tableView check the number of sections but a non-empty one does not?
问题描述
我用一个简单的 UITableViewController
设置了一个演示应用程序,没有内容,但工具栏中有一个添加"按钮.这将启动一个模态视图控制器,除了取消"按钮之外,它还是空的.取消按钮只是告诉它的 delegate
(UITableViewController
)关闭模态.
然后我在 UITableViewController
的 numberOfSectionsInTableView
方法中添加了一个 NSLog
语句.
通常,当表视图控制器加载时,我会看到两次对 numberOfSectionsInTableView
的调用.当我打开和关闭模式(返回到 UITableViewController
)时,我看不到对 numberOfSectionsInTableView
的进一步调用.
但是,如果我从 numberOfSectionsInTableView
返回 0
,除了显示的两个调用之外,当模态关闭时,我还会看到一个额外的 numberOfSections 调用.>
这仅在 numberOfSectionsInTableView
返回 0
时发生,而且我没有在我的项目中添加任何额外的代码.这很容易通过设置我所描述的几个控制器并修改 numberOfSectionsInTableView
的结果来验证.
我的问题:
- 为什么
UITableView
在从模态视图返回时调用numberOfSectionsInTableView
? - 为什么只在
numberOfSectionsInTableView
返回0
时才这样做? - 除了
numberOfSectionsInTableView
之外,UITableViewController
还会在模式关闭时调用cellForRowAtIndex:
.实际上,它正在尝试显示其dataSource
的新内容.如果添加的第一行已经自动更新,我打算如何手动为行插入设置动画?是否应该让我来确保我的UITableView
与其dataSource
一致? UITableViewController
检查什么属性以知道有一个或多个部分(因此询问我的代表有多少个部分)?它不能是numberOfSectionsInTableView
本身,因为每当我从模态返回时,我都会看到它被调用,而不仅仅是在 numberOfSections = 0 时.
当table view第一次被加载时,表视图控制器重新加载表视图的数据...UITableViewController
类在超类方法中实现了这个viewWillAppear:
如果您在调试器中观看,应用启动时的第二次调用来自 UITableViewController
的 viewWillAppear:
实现 - 特别是引用的部分到上面,tableView
被发送 reloadData
消息.
现在,启动时对 numberOfSectionsInTableView:
的第一次调用也是来自 UITableViewController
的 viewWillAppear:
实现> 但不是直接来自该实现对 -[UITableView reloadData]
的调用.我不确定第一个电话是关于什么的.
但是,对于您的问题,解除模态时发生的对 numberOfSectionsInTableView:
的调用与来自 applicationDidFinishLaunching 的 second 调用具有完全相同的调用堆栈:withOptions:
.我的假设是 UITableView
将零部分解释为处于完全未加载的状态.这确实有些道理.我认为空"表视图是一个没有任何行的视图,但一个没有任何部分的视图对我来说几乎是未初始化"的.此外,UITableViewDataSource
文档暗示 UITableView
默认有一个部分.从此方法返回零也与文档的假设不一致.
现在,关于动画的问题 - 如果你给表格一个空白部分来处理,你将能够完全控制用你想要的任何动画插入第一行,而不是被锁定当您需要重新加载时.
我认为这个故事的寓意是,不要返回零部分,除非您出于某种原因真的非常需要.您帖子的标题也提到此表视图为空",但我认为很明显框架发现零个部分不是空的而是已卸载.
希望这有帮助!感谢您发布示例项目供我使用.
I have set up a demo application with a simple UITableViewController
with no contents, but an 'Add' button in the toolbar. This launches a modal view controller which is again empty other than a 'cancel' button. The cancel button just tells its delegate
(the UITableViewController
) to dismiss the modal.
I then added an NSLog
statement in the UITableViewController
's numberOfSectionsInTableView
method.
Ordinarily, when the table view controller loads I see two calls to numberOfSectionsInTableView
. When I open and dismiss the modal (which returns to the UITableViewController
) I see no further calls to numberOfSectionsInTableView
.
However, if I return 0
from numberOfSectionsInTableView
, in addition to the two calls on display, I also see an additional numberOfSections call when the modal is dismissed.
This only happens when numberOfSectionsInTableView
returns 0
, and I have added no additional code to my project besides that mentioned. This is easily verifiable by setting up a couple of controllers as I've described and modifying the result from numberOfSectionsInTableView
.
My questions:
- Why is the
UITableView
callingnumberOfSectionsInTableView
on return from a modal view? - Why is it only doing this if
numberOfSectionsInTableView
returns0
? - In addition to
numberOfSectionsInTableView
, theUITableViewController
is also callingcellForRowAtIndex:
when the modal is dismissed. In fact, it is attempting to display the new contents of itsdataSource
. How am I meant to manually animate a row insertion if the first row added is going to already be updated automatically? Shouldn't it be left to me to make sure that myUITableView
is consistent with itsdataSource
? - What property is the
UITableViewController
checking to know that there is one or more sections (and therefore ask my delegate how many sections)? It can't benumberOfSectionsInTableView
itself, since I would see it called whenever I return from the modal, not only when numberOfSections = 0.
From UITableViewController
docs:
When the table view is about to appear the first time it’s loaded, the table-view controller reloads the table view’s data... The
UITableViewController
class implements this in the superclass methodviewWillAppear:
If you watch in the debugger, the second call upon app launch is from UITableViewController
's viewWillAppear:
implementation - specifically the part referred to above, where tableView
is sent the reloadData
message.
Now, the first call to numberOfSectionsInTableView:
on launch is also from UITableViewController
's implementation of viewWillAppear:
but not directly from that implementation's call to -[UITableView reloadData]
. I'm not sure what the first call is all about.
But, to your question, the call to numberOfSectionsInTableView:
that happens when dismissing the modal has exactly the same call stack as the second call from applicationDidFinishLaunching:withOptions:
. My hypothesis then is that UITableView
interprets having zero sections as being in a state where it has not loaded at all. That does make some sense actually. I'd consider an "empty" table view to be one without any rows, but one without any sections seems almost "uninitialized" to me. Furthermore the UITableViewDataSource
documentation implies UITableView
has by default one section. Returning zero from this method would be inconsistent with that assumption of the docs as well.
Now, to your concern about animation - if you give the table an empty section to work with, you will be able to have full control over inserting the first row with whatever animation you'd like, and not be locked in to when you need to reload.
I think the moral of the story is, don't return zero sections unless you really, really need to for some reason. The title of your post refers to this table view being "empty" as well but I think it's clear the framework finds zero sections to not be empty but unloaded.
Hope this helps! And thanks for posting the sample project for me to play around with.
这篇关于为什么空的 tableView 会检查部分的数量,而非空的则不会?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!