我有一个UISwitch作为accessoryView的UITableView。我的问题是,如果我切换其中一个开关,然后滚动,这样开关就看不见了,它就会返回到以前的状态。
请参阅video。
有没有人知道这可能是为什么以及如何解决它?
下面是添加switch视图并处理其操作的代码。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"POICell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier ];
//set the cell text to the
cell.textLabel.text = [self.catNames objectAtIndex:[indexPath row]];
NSString *toggle = [self.toggleArray objectAtIndex:[indexPath row]];
//add switch
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//create an instance of the database oject
DataBase * dataBase = [[DataBase alloc] init];
//open the database connection
[dataBase openDB];
NSString *imageName = [dataBase getPinImageNameFromCatID:[self.catIDs objectAtIndex:[indexPath row]]];
//get the root file path for the images
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/pinImages/%@",documentsDirectory, imageName];
//add image
NSURL *imageURL = [NSURL fileURLWithPath:filePath];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
NSLog(@"%@",[self.catIDs objectAtIndex:[indexPath row]]);
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;
[switchView addTarget:self action:@selector(switchChanged: ) forControlEvents:UIControlEventValueChanged];
if ([toggle isEqualToString: @"OFF"]) {
[switchView setOn:NO animated:NO];
}else{
[switchView setOn:YES animated:NO];
}
return cell;
}
- (void) switchChanged:(id)sender {
//get the switch that it was sent from
UISwitch *switchInCell = (UISwitch *)sender;
//get the cell it was sent from
UITableViewCell * cell = (UITableViewCell *) switchInCell.superview;
//get the row it was sent from
NSIndexPath * indexpath = [self.inputTableView indexPathForCell:cell];
//cast the indexpath to int
NSInteger variable = indexpath.row;
//set the filter as off in the user defualts.
[self.filterDic setValue:switchInCell.on ? @"ON" : @"OFF" forKey:[self.catIDs objectAtIndex:variable]];
//store the newdic in the user defualts
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
//save the dic to user defaults
[prefs setObject:self.filterDic forKey:@"pinFilters"];
}
谢谢你的帮助。
发布于 2013-01-25 20:22:07
你的代码有两个问题(至少:)
让我从让你迷惑的那个开始。您可以根据toggle
设置每个巫师的状态。而toggle
的值是从数组self.toggleArray
中取出来的。
到目前为止一切还好。但是,当一个值发生更改并调用switchChanged
操作时,您可以更新self.filterDic
,但不能更新self.toggleView
。
这就产生了问题:下次当一个单元格变得可见时,cellForRowAtIndexPath
会再次被调用,并且会根据toggle
设置值,这个值是基于self.toggleArray
的。它仍然保留着旧的价值观。你看?
您之所以犯这个错误,可能是因为您还没有完全了解细胞回收机制。这可能是导致我发现的第二个问题的原因。让我试着解释一下。iOS或cocoa分别尝试将视图单元格对象分配为必需品。这意味着滚动离开屏幕的单元格将被添加到池中,下次需要(类似) sell时可以从池中重用该单元格。因此,每次需要新的单元格(变为可见的单元格)时,都会调用cellForRowAtIndexPath
。这样你就可以使用dequeueReusableCellWithIdentifier
来获取一个单元格。如果池中存在用相同重用标识符初始化的单元,则将该单元(或其中之一)返回给调用者。在最近的iOS (相应的SDK版本)版本中,如果这些单元都不存在,则会分配并返回一个新的单元。(这就是为什么Murali的建议也不能完美工作的原因)在旧版本中,你必须检查cell中的nil和alloc/init,在这些情况下是新的。
在此之后,您可以自由地分配新的子视图对象,而不管该单元是否被重新循环,并且是否已经具有这些子视图。然后,您可以一次又一次地添加和添加相同的子视图。
你怎么解决这个问题呢?像往常一样,有几种方法可以解决这个问题:
首先-检查单元格是否被重用。只需检查开关是否已经存在。为此,您可以使用不同于0的值对其进行标记,并使用此标记获取子视图。如果你没有得到它,那么这个单元格是新的,你必须创建所有的附加子。
其次-在使用dequeueReusableCellWithIdentifier
获取单元格之后,您总是可以擦除单元格中的所有子视图。这是最简单的解决方案,因为您不必将mutch更改为现有代码。不过,这不是性能最好的解决方案。
第三,最优雅的解决方案可能是每次想要向单元格添加自定义元素时都将UITableViewCell
子类化。在这种情况下,它的init方法只会在创建时调用一次(并且不会在重用时调用),并且您可以通过编程方式添加所有定制的子视图。当然,您可以设计单元格并添加IB中的所有子视图,就像处理每个UIView
对象一样。在cellForRowAtIndexPath
中,您只需设置适当的值即可。
发布于 2013-01-25 19:52:50
发布于 2013-01-25 19:53:08
请使用此方法..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"POICell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UISwitch *switchView;
if (cell == nil)
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier ];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
switchView = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];//Change the frame
cell.accessoryView = switchView;
}
//set the cell text to the
cell.textLabel.text = [self.catNames objectAtIndex:[indexPath row]];
NSString *toggle = [self.toggleArray objectAtIndex:[indexPath row]];
//add switch
//create an instance of the database oject
DataBase * dataBase = [[DataBase alloc] init];
//open the database connection
[dataBase openDB];
NSString *imageName = [dataBase getPinImageNameFromCatID:[self.catIDs objectAtIndex:[indexPath row]]];
//get the root file path for the images
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:@"%@/pinImages/%@",documentsDirectory, imageName];
//add image
NSURL *imageURL = [NSURL fileURLWithPath:filePath];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
NSLog(@"%@",[self.catIDs objectAtIndex:[indexPath row]]);
[switchView addTarget:self action:@selector(switchChanged: ) forControlEvents:UIControlEventValueChanged];
if ([toggle isEqualToString: @"OFF"]) {
[switchView setOn:NO animated:NO];
}else{
[switchView setOn:YES animated:NO];
}
return cell;
}
https://stackoverflow.com/questions/14521208
复制相似问题