Ios UITableView中的NSMutableArray
我只是被困在这里,我不知道我做错了什么。我对目标c很陌生。在我的应用程序中,我使用Ios UITableView中的NSMutableArray,ios,objective-c,uitableview,Ios,Objective C,Uitableview,我只是被困在这里,我不知道我做错了什么。我对目标c很陌生。在我的应用程序中,我使用UITableView和NSMutableArray解析RSS提要中的数据。当用户单击tableview中的segment控件时,我想用新数据刷新整个表。我在表头部分添加了段控件,它可以在段索引更改时更改值 现在的问题是,当我单击段控件时,它会在tableview中添加新行,而不是刷新整个表。代码如下: - (void)addEarthquakesToList:(NSArray *)earthquakes
UITableView
和NSMutableArray
解析RSS提要中的数据。当用户单击tableview中的segment控件时,我想用新数据刷新整个表。我在表头部分添加了段控件,它可以在段索引更改时更改值
现在的问题是,当我单击段控件时,它会在tableview中添加新行,而不是刷新整个表。代码如下:
- (void)addEarthquakesToList:(NSArray *)earthquakes
{
//NSInteger startingRow = [self.earthquakeList count];
NSInteger earthquakeCount = [earthquakes count];
NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:earthquakeCount];
NSLog(@"%d",earthquakeCount);
for (NSInteger row = 0; row < (earthquakeCount); row++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
[indexPaths addObject:indexPath];
}
[self.earthquakeList addObjectsFromArray:earthquakes];
[self.tableView insertRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationAutomatic];
}
以下是我的tableView数据源方法:
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// The number of rows is equal to the number of earthquakes in the array.
return [self.earthquakeList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kEarthquakeCellID = @"EarthquakeCellID";
citsTableViewCell *cell = (citsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kEarthquakeCellID];
//Get the specific earthquake for this row.
citsFuelFinder *earthquake = (self.earthquakeList)[indexPath.row];
[cell configureWithEarthquake:earthquake];
return cell;
}
事实上,当尝试在段控件中包含以下内容时:
- (void)segmentedControlHasChangedValue
{
int product;
product = fuelType.selectedSegmentIndex;
switch (product)
{
case 0:
productName=1;
[locationManager startUpdatingLocation];
break;
case 1:
productName=2;
//[self.earthquakeList removeLastObject];
if (![self.earthquakeList count])
{
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationRight];
}
else
{
NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
for(unsigned int i = 0; i < [self.earthquakeList count]; i++)
{
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i
inSection:0]];
}
//[self.tableView beginUpdates];
//[self.earthquakeList removeAllObjects];
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
withRowAnimation:UITableViewRowAnimationFade];
//[self.tableView endUpdates];
[self.tableView reloadData];
//[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
[locationManager startUpdatingLocation];
break;
case 2:
productName=4;
[locationManager startUpdatingLocation];
break;
case 3:
productName=5;
[locationManager startUpdatingLocation];
break;
default:
break;
}
}
-(void)分段控件已更改值
{
int产品;
产品=fuelType.selectedSegmentIndex;
交换机(产品)
{
案例0:
productName=1;
[locationManager startUpdatingLocation];
打破
案例1:
productName=2;
//[自我地震师移除目标];
如果(![self.earthquakeList count])
{
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:0]
withRowAnimation:UITableViewRowAnimationRight];
}
其他的
{
NSMUTABLEARRY*indexPathsToDelete=[[NSMUTABLEARRY alloc]init];
for(无符号整数i=0;i<[self.earthquakeList count];i++)
{
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i
不确定:0]];
}
//[self.tableView开始更新];
//[自地震师移除所有对象];
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
withRowAnimation:UITableViewRowAnimationFade];
//[self.tableView endUpdates];
[self.tableView重载数据];
//[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]with RowAnimation:YES];
}
[locationManager startUpdatingLocation];
打破
案例2:
productName=4;
[locationManager startUpdatingLocation];
打破
案例3:
productName=5;
[locationManager startUpdatingLocation];
打破
违约:
打破
}
}
我得到这个错误:
由于未捕获异常而终止应用程序
'NSInternalInconsistencyException',原因:'无效更新:无效
节0中的行数。表中包含的行数
更新(15)后的现有节数必须等于
更新(15)之前该节中包含的行,加号或减号
从该节插入或删除的行数(插入0,
15)并加上或减去移入或移出的行数
该部分(0移入,0移出)。'
*第一次抛出调用堆栈:(0x2e332e83 0x3868f6c7 0x2e332d55 0x2ecdb0af 0x30c8a34d 0x30cb083f 0x6d2d9 0x30aebda3 0x30aebd3f)
0x30aebd13 0x30ad7743 0x30bf7c59 0x30bf7a27 0x30cbca25 0x30aaf1a1
0x30ae69fd 0x30ae63ab 0x30abbd79 0x30aba569 0x2e2fdf1f 0x2e2fd3e7
0x2E2FBD7 0x2e266471 0x2e266253 0x32fa02eb 0x30b1b845 0x6948d
0x38b88ab7)
非常感谢任何帮助 更新tableview的源数组,无需插入新行
[self.earthquakeList addObjectsFromArray:earthquakes];
[self.tableView reloadData];
如果向数据源数组中添加元素,则表视图中的行数将自动更新。您不需要插入行。只需插入元素。将您的方法实现为:
- (void)addEarthquakesToList:(NSArray *)earthquakes
{
[self.earthquakeList addObjectsFromArray:earthquakes];
[self.tableview reloadData];
}
呃,而不是
[self.tableView insertRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationAutomatic];
试一试
无论如何。。。。至少对我来说,您的代码片段仍然不足以找到您的问题 但既然你说:
当用户单击tableview中的segment控件时,我想用新数据刷新整个表。
如果我必须制作一个包含4个段的分段表格视图,为不同的段显示不同的数据,我会这样做:
注:这是一个基本示例。它不符合您的特定代码,但应该可以让您放弃使用IndExpath的逻辑,或者从数组中手动添加/删除对象,而是适当地使用tableView reloadData
- (void)viewDidLoad
{
[super viewDidLoad];
//declare NSArray *arrFirst, *arrSecond, *arrThird, *arrFourth, *arrSelected
//in the .h file
arrFirst = [[NSArray alloc] initWithObjects:@"eins",@"zwei",@"drei",@"vier",@"fünf",@"sechs", nil];
arrSecond = [[NSArray alloc] initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eigth",@"nine", nil];
arrThird = [[NSArray alloc] initWithObjects:@"uno",@"dos",@"tres",@"cuatro",@"cinco", nil];
arrFourth = [[NSArray alloc] initWithObjects:@"ek",@"do",@"teen",@"chaar",@"paach",@"che",@"saat", nil];
arrSelected = arrFirst;
}
我也可以使用单个数组来完成此操作,首先刷新旧数组内容:
arrSelected=nil
然后将新元素放入该数组中(使用某些逻辑从某个源中)
最后:
myTableView重新加载数据
您选择第二个段时,崩溃出现了吗因此,以下代码会导致错误
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
withRowAnimation:UITableViewRowAnimationFade];
使用deleteRowsAtIndexPaths或InsertRowsatindExpaths时,必须确保数据源的长度与tableView的当前行匹配。例如:您的tableView已经有10行,现在您需要删除2行,您应该首先从数据源数组中删除2个数据对象,然后调用deleteRowsAtIndexPaths。
尝试这些替换,并在以后给我们一些反馈(特别是如果任何NSAssert“崩溃”了您的应用程序):
因此,您要做的是始终让表在
self.earthquakeList
中显示数据,并在更新时清除所述数据?我理解正确吗?是的,完全正确。谢谢,无需插入新行。您可以更改数据源(earthquakeList)并重新加载TableView抱歉,我不确定您的意思。请你再详细一点…请编辑你的帖子,将这两种方法包括在内-numberOfRowsInSection&-CellForRowAtIndexPath谢谢,我尝试了你的第一个建议,但没有成功,它的行号错误。我尝试了-(void)clearData{[self.tableVie]
- (void)viewDidLoad
{
[super viewDidLoad];
//declare NSArray *arrFirst, *arrSecond, *arrThird, *arrFourth, *arrSelected
//in the .h file
arrFirst = [[NSArray alloc] initWithObjects:@"eins",@"zwei",@"drei",@"vier",@"fünf",@"sechs", nil];
arrSecond = [[NSArray alloc] initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eigth",@"nine", nil];
arrThird = [[NSArray alloc] initWithObjects:@"uno",@"dos",@"tres",@"cuatro",@"cinco", nil];
arrFourth = [[NSArray alloc] initWithObjects:@"ek",@"do",@"teen",@"chaar",@"paach",@"che",@"saat", nil];
arrSelected = arrFirst;
}
- (IBAction)mySegmentsAct:(UISegmentedControl *)sender
{
switch (sender.selectedSegmentIndex)
{
case 0:
arrSelected = arrFirst;
break;
case 1:
arrSelected = arrSecond;
break;
case 2:
arrSelected = arrThird;
break;
case 3:
arrSelected = arrFourth;
break;
default:
arrSelected = nil;
break;
}
[myTableView reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [arrSelected count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = (arrSelected)[indexPath.row];
return cell;
}
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
withRowAnimation:UITableViewRowAnimationFade];
- (void)addEarthquakesToList:(NSArray *)earthquakes
{
// data checking
NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
NSAssert(self.tableView != nil, @"tableView cannot be nil!");
NSAssert(earthquakes != nil, @"earthquakes cannot be nil!");
// relevant implementation
[self.earthquakeList addObjectsFromArray:earthquakes];
[self.tableView reloadData];
}
- (void)segmentedControlHasChangedValue
{
// data checking
NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
NSAssert(self.tableView != nil, @"tableView cannot be nil!");
NSAssert(fuelType != nil, @"fuelType cannot be nil!");
NSAssert(locationManager != nil, @"locationManager cannot be nil!");
// relevant implementation
switch (fuelType.selectedSegmentIndex)
{
case 0:
productName=1; // what is this?
[locationManager startUpdatingLocation];
break;
case 1:
productName=2;
[self.earthquakeList removeAllObjects];
[locationManager startUpdatingLocation];
break;
case 2:
productName=4;
[locationManager startUpdatingLocation];
break;
case 3:
productName=5;
[locationManager startUpdatingLocation];
break;
default:
break;
}
[self.tableView reloadData]; // if you want to change the data whenever the user changes the UISegmentedControl to any new value, leave this here.
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// data checking
NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
NSAssert(self.tableView != nil, @"tableView cannot be nil!");
// relevant implementation
[self.earthquakeList removeAllObjects];
[self.tableView reloadData];
}