首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在滚动UITableView时取消切换UISwitch

在滚动UITableView时取消切换UISwitch
EN

Stack Overflow用户
提问于 2013-01-25 19:48:11
回答 3查看 973关注 0票数 1

我有一个UISwitch作为accessoryView的UITableView。我的问题是,如果我切换其中一个开关,然后滚动,这样开关就看不见了,它就会返回到以前的状态。

请参阅video

有没有人知道这可能是为什么以及如何解决它?

下面是添加switch视图并处理其操作的代码。

代码语言:javascript
运行
复制
- (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"];

}

谢谢你的帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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中,您只需设置适当的值即可。

票数 1
EN

Stack Overflow用户

发布于 2013-01-25 19:52:50

也许你的细胞正在被回收。

看看这里被接受的答案:

iphone : uitableview : contents of a cell change on scrolling

票数 1
EN

Stack Overflow用户

发布于 2013-01-25 19:53:08

请使用此方法..

代码语言:javascript
运行
复制
- (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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14521208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档