首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在UITableView中保留占位符单元格

在UITableView中保留占位符单元格
EN

Stack Overflow用户
提问于 2011-01-05 04:56:27
回答 2查看 3.1K关注 0票数 4

我有一个UITableView,我从来不想让它少于1个单元格:它是一个目录读数,如果目录中没有文件,它就有一个单元格,上面写着“没有文件”。(在编辑模式中,有一个用于创建文件的奖励单元格,因此编辑模式永远不会低于两个单元格。)

这可能只是因为缺乏睡眠,让我现在无法从纸袋中思考,但我总是被这样的错误所绊倒:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
*** Terminating app due to uncaught exception 
'NSInternalInconsistencyException', reason: 'Invalid update: 
invalid number of sections.  The number of sections contained 
in the table view after the update (2) must be equal to 
the number of sections contained in the table view before 
the update (2), plus or minus the number of sections inserted 
or deleted (1 inserted, 0 deleted).'

这是因为我在删除最后一个文件之前先发制人地添加了"No Files“占位符。如果我在添加占位符之前删除最后一个文件单元格,就会发生like崩溃。无论采用哪种方法,单元计数都会与numberOfRowsInSection返回的结果不同步,从而触发崩溃。

对于这种情况,肯定有一种设计模式。给我提供线索?

EN

回答 2

Stack Overflow用户

发布于 2013-05-08 12:32:25

我对此有另一个解决方案(似乎有很多方法可以做到这一点)。我发现其他可用的解决方案不适合我的需求,所以我想出了这个。

这种方法非常简单,对于那些想要使用两个(或更多)占位符单元格、不想打乱数据模型或多个表格视图、以及(尤其是)需要允许在表格中删除和插入单元格的人来说,这种方法非常好用。它还允许非常好的输入和输出转换,以显示和隐藏占位符。

听上去不错?好的!让我们来看看它的基本要点:

大多数占位符单元格解决方案的真正问题是,当您开始允许对表进行编辑(删除和插入)时,它们通常会失败。否则,您必须开始处理处理编辑的代码,这可能会使一切变得更加混乱。这里的问题通常是在numberOfRowsInSection方法中返回不一致的值。tableview通常会遇到这样的问题:删除表格中的一个单元格,如果表格中只剩下一个单元格,并且在删除后还剩下一个单元格(或者插入时反之亦然)。

简单的解决方案是什么?我们总是有一个一致的单元格数量-数据源中的条目数量加上占位符的数量。占位符单元格总是存在的,它只是根据技术上是否应该存在来显示或隐藏它的内容。

尽管写得很长,但实现这一点实际上非常简单。让我们开始吧:

1.设置占位符单元原型:这非常简单。在情节提要中为占位符设置原型单元格。在我的例子中,我使用了两个:一个用来显示“正在加载...”当表格从服务器获取数据时,当表格中实际上没有任何内容时,显示“点击+上面添加项目”。

以您喜欢的方式设置您的单元格(我只是使用了副标题单元格样式,并将我的占位符文本放在了副标题标签中。如果这样做,不要忘记删除另一个标签的文本)。确保分配一个重用标识符,并将选择样式设置为“None”。

2.设置 numberOfRowsInSection 委托方法:这个方法现在将做两件基本的事情:第一是返回数据源中的行数(加上占位符的行数),第二是根据需要显示/隐藏占位符的文本。这是启动此操作的好地方,因为每次删除或插入单元格时都会调用此方法(实际上是两次;一次在编辑之前,一次在编辑之后)。为了避免每次调用方法时都运行动画,我们将使用BOOL placeholderIsHidden来跟踪占位符的当前状态。我们还将在短暂的延迟后执行切换,以便启动单元格编辑动画。将此代码添加到您的类中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int count = [self.dataSource count];

    // Hide/Show placeholder cell
    if (count == 0) {   // Placeholder should be shown
        if (self.placeholderIsHidden) {
            [self performSelector:@selector(animatePlaceholderCellChangeForIndexPath:) withObject:[NSIndexPath indexPathForRow:count inSection:0] afterDelay:0.1];
        }
    }
    else {   // Placeholder should be hidden
        if (!self.placeholderIsHidden) {
            [self performSelector:@selector(animatePlaceholderCellChangeForIndexPath:) withObject:[NSIndexPath indexPathForRow:count inSection:0] afterDelay:0.1];
        }
    }

    return count + 1;
}

这就可以开始了!现在让我们添加animatePlaceholderCellChange方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)animatePlaceholderCellChangeForIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.8];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationBeginsFromCurrentState:YES];

    if (indexPath.row == 0) {
        cell.detailTextLabel.hidden = NO;
        self.placeholderIsHidden = NO;
    }
    else {
        cell.detailTextLabel.hidden = YES;
        self.placeholderIsHidden = YES;
    }

    [UIView commitAnimations];
}

此方法利用动画块来平滑显示和隐藏占位符之间的过渡(并使其与单元格编辑动画很好地配合)。

倒数第二,我们需要设置cellForRowAtIndexPath方法来返回正确的单元格。

3. Setup cellForRowAtIndexPath**:**这是相当简单的。将此代码放入您的方法中,在您的原型单元标识符声明之后,并在进行正常的单元设置之前:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Add a placeholder cell while waiting on table data
int nodeCount = [self.dataSource count];

if (indexPath.row == nodeCount) {
     // Place the appropriate type of placeholder cell in the first row
     if (self.isLoading) {
         return [tableView dequeueReusableCellWithIdentifier:LoadingCellIdentifier];
     }
     else {
         return [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
     }
 }

最后,让我们设置BOOL属性来跟踪数据是否正在加载,以及占位符是否隐藏。

4.设置isLoading placeholderIsHidden**:**

首先,将这两个声明添加到类的.h文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@property (assign, nonatomic) BOOL isLoading;
@property (assign, nonatomic) BOOL placeholderIsHidden;

现在,在viewDidLoad方法中设置它们的初始值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
self.isLoading = YES;
self.placeholderIsHidden = NO;

这就是placeholderIsHidden属性!至于isLoading属性,您需要在代码开始从服务器加载数据的任何地方将其设置为YES,在该操作完成的任何地方设置为NO。在我的例子中,它相当简单,因为当加载操作完成时,我使用了一个带有回调的操作。

就这样!运行您的代码,并看到整洁,流畅的动画和编辑安全的占位符单元格!

希望这对某些人有帮助!

编辑:更重要的一件事!重要的是要注意,你应该对你的代码做另外一件事,以避免任何讨厌的不必要的崩溃:检查你的代码,无论你在哪里访问数据源中的元素(通常使用objectAtIndex:),确保你永远不会试图拉出一个不存在的元素。

在极少数情况下,这可能是一个问题,例如,您有访问数据源中所有可见行的元素的代码(由于占位符可能是可见的,因此您的indexPath可能与数据源中的任何元素都不相关)。(在我的例子中,这是一段特定的代码,一旦表格视图完成滚动,它就会在所有可见行上启动图像下载)。解决这个问题非常简单:无论您在何处访问数据源中的元素,都可以像这样在代码周围添加if语句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int count = [self.dataSource count];

if (indexPath.row != count) {

   // Code that accesses the element
   // ie:
   MyDataItem *dataItem = [self.dataSource objectAtIndex:indexPath.row];
}

祝好运!

票数 3
EN

Stack Overflow用户

发布于 2011-10-08 04:45:29

absolute实现这一点最简单的方法是实际拥有两个UITableViews

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UITableView * mainTable; 
UITableView * placeholderTable;

然后在你的委托中做一些事情,比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tableView:(UITableView*)tableview cellForRowAtIndexPath:(NSIndexPath*)indexPath {
  if (tableview == placeholderTable){
    // code for rendering placeholder cell
  }
  else {
    // code for rendering actual table content
  }
}

无论何时插入/删除实体或初始化视图,都要检查是否为空,并隐藏/取消隐藏表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// something changed the number of cells
    if (tableIsEmpty){
      mainTable.hidden = YES;
      placeholderTable.hidden = NO;
    }
    else {
      mainTable.hidden = NO;
      placeholderTable.hidden = YES;
    }

这样做将为您节省大量痛苦;尤其是在使用核心数据NSFetchedResultsController和表视图动画时。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4600948

复制
相关文章
使用jquery获取url及url参数的方法
使用jquery获取url以及使用jquery获取url参数是我们经常要用到的操作
Jensen_97
2023/07/19
1.5K0
python-获取URL中的json数据
数据源为某系统提供的URL,打开是json文件,python代码获取如下: URL替换成自己的即可。 import urllib.request def get_record(url): resp = urllib.request.urlopen(url) ele_json = json.loads(resp.read()) return ele_json if __name__ == '__main__': print(get_record('http://abc.co/
py3study
2020/01/16
5.5K0
dns url转发_获取url参数的方法
DNSPod是一款免费智能DNS产品,可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。
全栈程序员站长
2022/11/02
6.4K0
使用js获取url中的get参数并转成json格式
写在前面的 没啥说的 上代码 思路就是先获取到?后面的参数区,然后 利用字符串转数组方法获取到各个参数 var json = {}; var url = 'https://www.ba
Theone67
2019/11/21
6.3K0
js获取url参数的方法
js获取url参数的方法有很多。 1.正则分析 function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } 调用方法: alert(GetQueryString("
水击三千
2018/02/27
19.7K0
封装获取url参数的方法
功能需求:前端页面来回切换需要我们去获取URL的某个参数值。这时封装一个输入参数名获取对应参数值的函数是很有必要的; //取url上的id function getQueryString(name) { //取url上的id var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r !
青梅煮码
2023/02/18
1.7K0
【API架构】使用 JSON API 的好处
在 API 工艺的世界里,没有比设计更受热议的领域了。从 REST、gRPC 到 GraphQL,有许多方法可以设计和标准化 Web API 交互。今天,我们将注意力转向另一种方法,JSON API,JSONAPI.org 上详细介绍的用于构建 API 的规范。
架构师研究会
2022/05/29
2.8K0
图片url地址的生成获取方法
在写博客插入图片时,许多时候需要提供图片的url地址。作为菜鸡的我,自然是一脸懵逼。那么什么是所谓的url地址呢?又该如何获取图片的url地址呢?
全栈程序员站长
2022/11/08
15.9K0
图片url地址的生成获取方法
封装方法,获取url地址上的参数
https://jiangsihan.cn/?id=123&name=hhh getQueryVariable(variable) { var query = window
江一铭
2022/06/17
1.4K0
封装方法,获取url地址上的参数
php – 通过curl从url获取JSON数据「建议收藏」
我试图通过curl连接从URL获取JSON数据.当我打开链接时:它显示{“version”:“N / A”,“success”:true,“status”:true}. 现在,我希望获得以上内容.
全栈程序员站长
2022/07/11
4K0
javascript/jquery获取地址栏url参数的方法
1、jquery获取url window.location.href; 2.通过javascript是如何获取url中的某个参数 function getUrlParam(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 if (r!=null) return unes
Yiiven
2022/12/15
1.9K0
[转载]javascript/jquery获取地址栏url参数的方法
本篇文章主要是对javascript/jquery获取地址栏url参数的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
小小鱼儿小小林
2020/06/24
3.5K0
如何使用 Go 语言获取 URL?
在 Web 开发和网络爬虫等领域,经常需要获取和处理 URL(统一资源定位符)。Go 语言提供了丰富的标准库来处理 URL,使得获取和解析 URL 变得简单而高效。本文将介绍如何使用 Go 语言获取 URL 的详细步骤,并提供一些实用的示例。
网络技术联盟站
2023/07/03
7810
如何使用 Go 语言获取 URL?
WordPress 获取当前页面 URL 地址的方法
通过 WordPress 原生的函数来,或者自定义函数,都可以获取当前页面的 URL 地址。
Yangsh888
2022/03/24
1.2K0
WordPress 获取 URL 链接路径的几种方法
其实对于 WordPress 开发方面来讲使用 ID 是最为方便快捷的,但是如果在 WordPress 固定链接中也使用文章 ID 等方式来展现虽然足够简单,却也失去了更加漂亮的 URL 以及关键词优化,所以最近子凡在开发百度小程序时需要充分的使用到百度智能小程序的自然搜索功能,需要提交 URL 适配规则,那么对于网站 URL 并不是 ID 的情况来说,小程序如果使用 ID 传参,这个适配规则基本就不在一个空间了。
张子凡
2022/11/02
1.2K0
WordPress 获取 URL 链接路径的几种方法
Akismet插件获取key API的方法
作者:matrix 被围观: 2,308 次 发布时间:2011-09-25 分类:Wordpress 兼容并蓄 | 2 条评论 »
HHTjim 部落格
2022/09/26
6850
Akismet插件获取key API的方法
Python - 使用 Tinyurl API 的 URL 缩短器
在网络时代,简洁的链接对于通过社交网站、短信和其他通信方式分发超链接至关重要。但是,冗长的 URL 可能会在共享时带来挑战,并且在发送消息时可能会被截断。长 URL 通常难以记忆,并且输入起来可能非常笨拙。为了解决手头的问题,创建了诸如TinyURL之类的网址缩短平台来管理职责。Python 提供了一种方便的方法来连接这些选项。在这篇文章中,我们将编写一个Python代码来与TinyURL网站API系统互动。
很酷的站长
2023/08/11
4310
Python - 使用 Tinyurl API 的 URL 缩短器
Vue获取url网址参数的两种方法
2、如果路由中没有传参(https://w3h5.com/detail),会报错页面无法显示。正常链接应该为 https://w3h5.com/detail/234
德顺
2020/04/26
31K1
点击加载更多

相似问题

友好的配置文件URL与控制器混在一起

25

空手道摘要报告在升级到1.0.0后没有显示所有经过测试的特性

12

如何从另一个空手道特性文件中调用依赖JAR中的空手道特性?

10

黄瓜报告中称为特性/场景的空手道显示标题

10

空手道:从被调用的特性文件中处理soap响应

111
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文