保存UITableView单元附件的状态?

时间:2012-12-28 18:09:54

标签: objective-c ios cocoa-touch uitableview

我在桌面视图上设置了手势识别器。

  • 向右滑动,附件变为刻度图像
  • 向左滑动并更改为V形图像

如果点击了一个单元格,它会加载一个本地HTML文件。

如果向右滑动,则勾号显示为应该。但是,如果您再点击一个单元格以查看HTML文件并返回到表格视图,则图像将恢复为V形图。

确保蜱保持原样的最佳方法是什么?


修改

进一步的代码:

来自'viewDidLoad':

UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                                                 action:@selector(handleSwipeRight:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.tableView addGestureRecognizer:recognizer];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                       action:@selector(handleSwipeLeft:)];
//recognizer.delegate = self;
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.tableView addGestureRecognizer:recognizer];


- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)gestureRecognizer
{
//Get location of the swipe
CGPoint location = [gestureRecognizer locationInView:self.tableView];

//Get the corresponding index path within the table view
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];

//Check if index path is valid
if(indexPath)
{
    //Get the cell out of the table view
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    //Update the cell or model

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"disclosure.png"]];
}
}

- (void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
CGPoint location = [gestureRecognizer locationInView:self.tableView];

NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];

if(indexPath)
{
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    // cell.accessoryType = UITableViewCellAccessoryCheckmark;
    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tick.png"]];
}

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

static NSString *simpleTableIdentifier = @"MFGCell";

MFGCell *cell = (MFGCell *) [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MFGCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];
}

cell.itemTitle.text = [item objectAtIndex:indexPath.row];
cell.itemDescription.text = [description objectAtIndex:indexPath.row];
cell.itemImageView.image = [UIImage imageNamed:[icons objectAtIndex:indexPath.row]];

return cell;
}

3 个答案:

答案 0 :(得分:2)

作为对用户滑动的反应,您应该存储用户的选择(例如,在NSMutableArray类型的私有实例变量中)。当用户返回到表格视图时,您可以重复使用tableView:cellForRowAtIndexPath:中的信息来设置具有正确附件样式的单元格。

财产声明:

@property(nonatomic, retain) NSMutableArray* _accessoryStyle;

合成属性。然后将此代码段添加到handleSwipeLeft:的底部以存储用户的选择:

- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)gestureRecognizer
{
  [...]
  NSNumber* number = [numberWithInt:0];
  [_accessoryStyle replaceObjectAtIndex:indexPath.row withObject:number];
}

handleSwipeRight:

的底部添加一个类似的代码段
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
  [...]
  NSNumber* number = [numberWithInt:1];
  [_accessoryStyle replaceObjectAtIndex:indexPath.row withObject:number];
}

tableView:cellForRowAtIndexPath:

NSString* accessoryImageName;
NSNumber* number = [_accessoryStyle objectAtIndex:indexPath.row];
switch ([number intValue])
{
  case 0:
    accessoryImageName = @"disclosure.png";
    break;
  case 1:
    accessoryImageName = @"tick.png";
    break;
  default:
    // replace with your error handling code
    return nil;
}
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:accessoryImageName]];

要使所有这一切正常工作,您需要使用与您希望表视图具有单元格相同数量的元素来初始化_accessoryStyle数组。例如,在视图控制器的viewDidLoad

- (void) viewDidLoad
{
  [super viewDidLoad];

  self._accessoryStyle = [NSMutableArray arrayWithCapacity:0];
  NSNumber* defaultAccessoryStyle = [numberWithInt:0];
  int numberOfRows = 17;  // get the real number from somewhere
  for (int index = 0; index < numberOfCells; ++index)
    [_accessoryStyle addObject:defaultAccessoryStyle];
}

为了平衡这一点,你需要添加

- (void) viewDidUnload
{
  [super viewDidUnload];
  self._accessoryStyle = nil;
}

仍有很大的改进空间:

  • 找到更好的变量名称
  • 对不同的样式使用枚举,而不是仅使用硬编码的数字0和1
  • 不要为每个表格视图单元格分配新的UIImageView,只需分配其中两个并根据附件样式使用正确的一个

答案 1 :(得分:0)

对于您的问题,存在一个潜在的逻辑问题,因为当它不应该触发滑动左侧事件或者刚刚卸载视图并重置为默认值时。查看事件触发时是否可以记录;否则应保留视图的状态。我还要做的是添加一个额外的状态变量,如int currentCellState,当你进入不同的状态来跟踪你的状态时你会改变它。然后在viewDIdLoad中确保您的所有数据和视图都保持同步,即currentCellState的值与您的观看状态相匹配。

答案 2 :(得分:0)

执行此操作的最佳方法是将您拥有的图像/按钮放在一个数组中,每次加载视图时,都会显示选择了哪个索引的项目。 为了做到这一点,应该将swipeMethode修改为类似这样的东西

-(void)swipeMethod: (UISwipeGestureRecognizer *) sender
{
    if(sender.direction == 
        UISwipeGestureRecognizerDirectionLeft && index < [myArray count]){   
        [self setSelectedIndex:index+1  animated:YES];  
        index++;
    }else if (sender.direction == UISwipeGestureRecognizerDirectionRight && index > 0) {
        [self setSelectedIndex:index-1 animated:YES]; 
        index--;
    }else {
        return;
    }
}

在viewDidLoad中添加以下代码:

    leftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeMethod:)];
    [leftRecognizer setDirection: UISwipeGestureRecognizerDirectionLeft];
    [self.tableView addGestureRecognizer:leftRecognizer];

    rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeMethod:)];
    [rightRecognizer setDirection: UISwipeGestureRecognizerDirectionRight];
    [self.tableView addGestureRecognizer:rightRecognizer];