为什么我写删除UITableView行的代理时江来出了问题要负泽

UITableView 系列四 :项目中行的操作 (添加移动和删除)(实例) - Just Code - ITeye技术网站
博客分类:
这篇文章主要讲的表格的操作包括:标记行、移动行、删除行、插入行。
这次就不从头建立工程了,在下载工程。这个工程就是最简单的产生一个表格并向其中写入数据。用Xcode 4.2打开它,在这个工程基础上实现以上操作。
这里讲的标记行指的是单击此行,可以实现在此行右边出现一个勾,如下图所示:
为了实现标记功能,在ViewController.m中@end之前添加代码:
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *oneCell = [tableView cellForRowAtIndexPath: indexPath];
if (oneCell.accessoryType == UITableViewCellAccessoryNone) {
oneCell.accessoryType = UITableViewCellAccessoryC
oneCell.accessoryType = UITableViewCellAccessoryN
[tableView deselectRowAtIndexPath:indexPath animated:YES];
该代码实现:单击某行时,若此行未被标记,则标记此行;若此行已经被标记,则取消标记。
运行效果如上图。
上面的代码实际上就是修改某行的accessoryType属性,这个属性可以设为四个常量:
UITableViewCellAccessoryCheckmark
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryNone
效果依次如下图所示:
UITableViewCellAccessoryCheckmark
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryNone
注意,上面第二张图片中的蓝色圆圈不仅仅是一个图标,还是一个控件,点击它可以触发事件,在上一篇博客《iOS开发16:使用Navigation Controller切换视图》使用过。
想要实现移动或者删除行这样的操作,需要启动表格的编辑模式。使用的是setEditing:animated:方法。
2.1 打开ViewController.xib,将其中的表格控件映射成Outlet到ViewController.h,名称为myTableView。
2.2 打开ViewController.m,在viewDidLoad方法最后添加代码:
//启动表格的编辑模式
[self.myTableView setEditing:YES animated:YES];
2.3 在@end之前添加代码:
//打开编辑模式后,默认情况下每行左边会出现红的删除按钮,这个方法就是关闭这些按钮的
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleN
//这个方法用来告诉表格 这一行是否可以移动
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
//这个方法就是执行移动操作的
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)
sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
NSUInteger fromRow = [sourceIndexPath row];
NSUInteger toRow = [destinationIndexPath row];
id object = [list objectAtIndex:fromRow];
[list removeObjectAtIndex:fromRow];
[list insertObject:object atIndex:toRow];
editingStyleForRowAtIndexPath这个方法中用到了常量UITableViewCellEditingStyleNone,它表示不可编辑,这里的编辑指的是删除和插入。表示表格行的编辑模式的常量有:
UITableViewCellEditingStyleDelete
UITableViewCellEditingStyleInsert
UITableViewCellEditingStyleNone
顾名思义,第一个表示删除,第二个表示插入,第三个表示不可编辑。
若将editingStyleForRowAtIndexPath方法中的UITableViewCellEditingStyleNone依次换成上面三个值,则它们运行的效果依次如下图所示:
2.4 运行,从下图可以看到实现了行的移动:
但是也会发现,现在无法对每行进行标记了。这说明,在编辑模式下,无法选择行,从而didSelectRowAtIndexPath这个方法不会执行。
从第2步过来,实现删除某行,其实比较简单了。
3.1将editingStyleForRowAtIndexPath方法中的UITableViewCellEditingStyleNone修改成UITableViewCellEditingStyleDelete。
3.2 在@end之前添加代码:
//这个方法根据参数editingStyle是UITableViewCellEditingStyleDelete
//还是UITableViewCellEditingStyleDelete执行删除或者插入
- (void)tableView:(UITableView *)tableView commitEditingStyle:
(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSUInteger row = [indexPath row];
[self.list removeObjectAtIndex:row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
在这个方法中又出现了一个常量:UITableViewRowAnimationAutomatic,它表示删除时的效果,类似的常量还有:
UITableViewRowAnimationAutomatic
UITableViewRowAnimationTop
UITableViewRowAnimationBottom
UITableViewRowAnimationLeft
UITableViewRowAnimationRight
UITableViewRowAnimationMiddle
UITableViewRowAnimationFade
UITableViewRowAnimationNone
它们的效果就不一一介绍了,可以在实际使用时试试。
3.3 运行,看看效果:
刚运行时显示如左边的图片,点击某一行左边的圆圈图标,会显示如中间图片所示。然后点击Delegate按钮,那一行就会被删除掉,如右边的那张图片所示,它显示的是删除时的效果。
这个与删除行类似。
4.1 首先将editingStyleForRowAtIndexPath方法中的UITableViewCellEditingStyleDelete修改成UITableViewCellEditingStyleInsert。
4.2在3.2添加的方法中添加代码:
//我们实现的是在所选行的位置插入一行,因此直接使用了参数indexPath
NSArray *insertIndexPaths = [NSArray arrayWithObjects:indexPath,nil];
//同样,将数据加到list中,用的row
[self.list insertObject:@"新添加的行" atIndex:row];
[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
上面的代码中也可以不用insertRowsAtIndexPaths方法,而直接使用[tableView reloadData];语句,但是这样就没有添加的效果了。
4.3 好了,运行一下:
刚运行时如上面左图所示,单击了某个加号后,新的一行就从右边飞进来了,因为在insertRowsAtIndexPaths中用了参数UITableViewRowAnimationRight。
下载次数: 100
浏览 13985
浏览: 8816522 次
来自: 洛杉矶
代码里有错误xxNew -&xNew, yyNew -& ...
PHP 生成 PDFhttp://www.51ask.org/ ...
我想问下那个111.1是怎么得来的
楼上这里错了BITMAP_&TYPT&_B ...2532人阅读
错误:&The number of sections contained in the table view after the update (1) 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 (0 inserted, 0 deleted).
功能思路其实不难,交代一下,我自己要实现的效果:
1.TableView是分组的。
2.点击删除按钮后,某行被删除。
写完大概功能,运行之后,出现:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:1070
libc++abi.dylib: handler threw exception
1.在调用deleteRowsAtIndexPaths:方法前,要确保数据为最新。也就是说,先将要删除的数据从数据源中删除。
2.分组和分组中行数是变动的,不能写成死的!
3.如果是分组,你会发现很怪的现象:当一个分组中,有多条数据时,你删除其中一条,正确;当一个分组中,你要删除唯一的一条时,仍然会报出如上的错误!
本人,就是百思不得其解。反复调试,数据已经保持最新了的。
在网上搜了很多,却没有满意答案。
灵感闪过!~~~~
删除某个分组中的最后一条数据时,分组数,和行数都要变。这时候,只调用了deleteRowsAtIndexPaths方法。也就是说,只对行数进行了操作,但是没有对变动的分组进行操作!
查看帮助API,找到这么一个方法:deleteSections:方法!
加上去,在删除某个分组中最后一条记录时,将该分组也删除!
搞定!搞定!
最后,贴一下,实现的关键思路:
1.计算分组数。
- (NSInteger)numberOfSectionsInTableView:(UITableView&*)tableView{
&&&&return&[_arrKeys&count];//
_arrKeys中存放分组
2.计算每个分组中的个数。
- (NSInteger)tableView:(UITableView&*)tableView
numberOfRowsInSection:(NSInteger)section{
&&&&NSString* _date = [_arrKeys&objectAtIndex:section];
&&&&NSArray* _notifications = [_dictData&objectForKey:_date];//
_dictData存放数据
&&&&return&[_notifications&count];
3.添加删除功能的代理方法(核心代码)。
- (void)tableView:(UITableView&*)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath
&&&&if&(editingStyle
==&UITableViewCellEditingStyleDelete) {
&&&&&&&&[self&refreshData];//&刷新_arrKeys和_dictData中的数据
&&&&&&&&int&newCount=0;
&&&&&&&&if&(indexPath.section&[_arrKeys&count])
&&&&&&&&&&&&NSString&*_date = [_arrKeys&objectAtIndex:indexPath.section];
&&&&&&&&&&&&NSArray* _notifications = [_dictData&objectForKey:_date];//
_dictData存放数据
&&&&&&&&&&&&newCount= [_notifications&count];
&&&&&&&&[tableView&beginUpdates];
&&&&&&&&if&(newCount&=0) {
&&&&&&&&&&&&[tableView&deleteSections:[NSIndexSetindexSetWithIndex:indexPath.section]&withRowAnimation:UITableViewRowAnimationLeft];
&&&&&&&&[tableView&deleteRowsAtIndexPaths:[NSArray&arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationLeft];
&&&&&&&&[tableView&endUpdates];
&&&&else&if&(editingStyle
==&UITableViewCellEditingStyleInsert) {
&&&&&&&&//&修改时
实现效果图:
1.遇到问题,查百度,谷歌!
2.先不忙写,做些小的Demo,搞清楚问题出在那里!
3.看苹果API(会告诉我们很多机制,原理性的东西)!
4.灵感!源于专注!
希望对你有所帮助!
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:61394次
积分:1158
积分:1158
排名:千里之外
原创:53篇
转载:27篇
(1)(1)(1)(1)(1)(1)(4)(1)(3)(3)(1)(6)(10)(5)(6)(4)(12)(9)(2)(7)(1)问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
报错信息:reason: '* -[__NSArrayM objectAtIndex:]: index 12 beyond bounds [0 .. 11]'删除8行之后就会报错 是什么原因?代码
-(NSMutableArray *)dataList{
if (_dataList ==nil) {
_dataList=[NSMutableArray array];
for (int i =0; i&20; i++) {
NSString *numberString =[NSString stringWithFormat:@"%d",arc4random_uniform(100000)];
[_dataList addObject:numberString];
return _dataL
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 20;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell =[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
NSString *numberString = self.dataList[indexPath.row];
cell.textLabel.text =numberS
#pragma mark - cell编辑
(nullable NSArray &UITableViewRowAction &)tableView:(UITableView )tableView editActionsForRowAtIndexPath:(NSIndexPath )indexPath {
UITableViewRowAction *action3 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self.dataList removeObjectAtIndex:indexPath.row];
[_tableView reloadData];
NSArray *actionArray = @[action3];
return actionA
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
你看看你这里面写死了20,你self.dataList总共20个,删除了8个之后就只剩下了12个了,你在reload的时候,tableview计算第12个cell的时候(0-12),NSString *numberString = self.dataList[indexPath.row];,从数组中取第12个,但是你数组里面总共是0-11个,这不数组越界了嘛。
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 20;
所以你这不能写死,要改成这样:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataList.
另外再补充一句,一般来说,如果只是删除,不涉及到其他变动的话,没必要全部reload,只需要reload从删除那行及其以下的位置,这样可以节约一些不必要的性能浪费。
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
扫扫下载 App1037人阅读
ios开发(35)
实现多行删除的基本思路:
UITableViewCellEditingStyle返回的如果是UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleI 编辑表的时候就会出现多选按钮.我们可以将所有选中单元格对应的indexPath存放到一个可变数组中,然后点击删除按钮时移除数据中对应的元素.
#import "MainViewController.h"
@interface MainViewController ()
UIButton * editB
NSMutableArray * dataA
NSMutableArray * selectedA
@implementation MainViewController
- (void)dealloc{
[dataArray release]; dataArray = nil;
[_tableView release]; _tableView = nil;
[super dealloc];
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
return self;
- (void)viewDidLoad
[super viewDidLoad];
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 480- 44) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
[self setTableViewHeaderView];
[self.view addSubview:_tableView];
dataArray = [[NSMutableArray alloc]initWithObjects:@"大葫芦",@"大娃",@"二娃",@"三娃",@"四娃",@"五娃",@"六娃",@"七娃", nil];
selectedArray = [[NSMutableArray alloc]init];
- (void)setTableViewHeaderView{
UIView * view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 60)];
editButton = [UIButton buttonWithType:UIButtonTypeCustom];
editButton.frame = CGRectMake(120, 5, 80, 50);
[editButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[editButton setTitle:@"delete" forState:UIControlStateNormal];
[editButton addTarget:self action:@selector(deleteSeletions:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:editButton];
self.tableView.tableHeaderView =
#pragma mark - 删除按钮的监听事件
- (void)deleteSeletions:(UIButton *)button{
NSString * title = self.tableView.editing ? @"delete" : @"ok";
[button setTitle:title forState:UIControlStateNormal];
self.tableView.editing = !self.tableView.editing;
int count = selectedArray.count;
if (count == 0) {
for (int i = 0 ; i & count - 1; i ++) {
for (int j = 0 ; j & count - 1 - j++) {
NSIndexPath * indexPath1 = [selectedArray objectAtIndex:j];
NSIndexPath * indexPath2 = [selectedArray objectAtIndex:j+1];
if (indexPath1.row & indexPath2.row) {
[selectedArray exchangeObjectAtIndex:j withObjectAtIndex:j+1];
for (int i = count-1 ; i &= 0; i--) {
NSIndexPath * indexPath = [selectedArray objectAtIndex:i];
[dataArray removeObjectAtIndex:indexPath.row];
[selectedArray removeAllObjects];
[self.tableView reloadData];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return dataArray.count;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * cellID = @"cellID";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
cell.textLabel.text = [dataArray objectAtIndex:indexPath.row];
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleI
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
#pragma mark - 选中单元格时方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if ([editButton.titleLabel.text isEqualToString:@"ok"]) {
[selectedArray addObject:indexPath];
#pragma mark - 取消选中单元格方法
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
if ([editButton.titleLabel.text isEqualToString:@"ok"]) {
[selectedArray removeObject:indexPath];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:49341次
积分:1148
积分:1148
排名:千里之外
原创:67篇
(4)(3)(1)(10)(10)(1)(12)(1)(1)(10)(18)

我要回帖

更多关于 额头长斑是哪出了问题 的文章

 

随机推荐