iPhone UITableViewController在执行期间显示/隐藏行

时间:2010-07-16 11:13:11

标签: iphone uitableview

我正在尝试实现一个包含7个部分的UITableViewController。每个部分都有许多行,可以根据用户事件进行更改。对于istance,在第一部分中我有一行带有UISwitch:如果用户激活了该开关,则该部分中会出现另外两行。第2节也是如此。现在好了.... 在3,4,5节我也有一行(Value1 Cell,iPhone常规设置之类):通过按下该单元格,这些部分在第二行显示一个带有3个段的UISegmented控件。通过按下其中一个段,用户做出选择并且分段控制行消失,这些段再次有一行,其值选择为detailTextLabel。

好吧,所有这些过程都是使用reloadSections方法管理的,该方法在用户正在进行交互时重新加载这些部分。我的代码如下:

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

UITableViewCell *cell = [ tableView dequeueReusableCellWithIdentifier: CellIdentifier];
CellIdentifier = [ NSString stringWithFormat: @"%d:%d", [ indexPath indexAtPosition: 0 ], [ indexPath indexAtPosition:1 ]]; 

//cell = nil;
if(indexPath.section == 0 && [indexPath indexAtPosition: 1] == 0)
{
    CellIdentifier = @"test";
}


if (cell == nil) {
    cell = [ [ [ UITableViewCell alloc ] initWithFrame: CGRectZero reuseIdentifier: CellIdentifier] autorelease ];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    switch ([ indexPath indexAtPosition: 0]) {
        case(0): {
            switch([ indexPath indexAtPosition: 1]) {
                case(0):
                {
                    positionControl.tag = 0;
                    [positionControl addTarget:self action:@selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
                    [ cell addSubview: positionControl ];
                    cell.textLabel.text = NSLocalizedString(@"Position",@"");

                }
                    break;
                case(1):
                {
                    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; 
                    cell.textLabel.text = NSLocalizedString(@"Some Position",@"");
                    cell.detailTextLabel.text = NSLocalizedString(@"Last Known Position",@"");
                }
                    break;
                case(2):
                {
                    cell.textLabel.text = NSLocalizedString(@"ReDo Position",@"");
                    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
                }
                    break;
            }
        }
            break;
        case(1): {
            switch ([ indexPath indexAtPosition: 1 ]) {
                case(0):
                {
                    photoControl.tag = 1;
                    [photoControl addTarget:self action:@selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
                    [ cell addSubview: photoControl ];
                    cell.textLabel.text = NSLocalizedString(@"photos",@"");
                }
                    break;
                case(1):
                {
                    cell.textLabel.text = NSLocalizedString(@"Take photo",@"");
                    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
                }
                    break;
                case(2):
                {
                    cell.textLabel.text = NSLocalizedString(@"Select from Roll",@"");
                    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
                }
                    break;
            }
        }
            break;
        case(2): {
            switch ([ indexPath indexAtPosition: 1 ]) {
                case(0):
                {

                    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
                    cell.textLabel.text = NSLocalizedString(@"size",@"");
                    if (UISegmentedControlNoSegment != [dimensionSegmentedControl selectedSegmentIndex]) {
                        cell.detailTextLabel.text = [dimensionSegmentedControl titleForSegmentAtIndex:[dimensionSegmentedControl selectedSegmentIndex]];
                    }
                    else {
                        cell.detailTextLabel.text = NSLocalizedString(@"Select",@"");
                    }
                }
                    break;
                case(1):
                {
                    [dimensionSegmentedControl addTarget:self action:@selector(onSegmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
                    [cell.contentView addSubview:dimensionSegmentedControl];
                }
                    break;
            }
        }
            break; ...

然后我的开关行动:

- (IBAction) toggleSwitch: (id) sender {
UISwitch *switchControl = (UISwitch *) sender;
NSUInteger tag = switchControl.tag;
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:tag];
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
[sectionsToReload release];}

分段控制的行动

- (IBAction) onSegmentedControlChanged: (id) sender {
UISegmentedControl *segmentedControl = (UISegmentedControl *) sender;
NSUInteger tag = segmentedControl.tag;
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:tag];
segmentedControl.momentary = YES;
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
segmentedControl.momentary = NO;
[sectionsToReload release];}

这是didSelectRow

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch ([ indexPath indexAtPosition: 0]) {      
    case(2): {
        switch([ indexPath indexAtPosition: 1]) {
            case (0): {
                if (UISegmentedControlNoSegment != [dimensionSegmentedControl selectedSegmentIndex]) {
                    dimensionSegmentedControl.selectedSegmentIndex = [dimensionSegmentedControl selectedSegmentIndex];
                }
                else {
                    dimensionSegmentedControl.selectedSegmentIndex = 0;
                }
                NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:2];
                //[self.tableView reloadData];
                [self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
                [tableView deselectRowAtIndexPath:indexPath animated:YES];
                [sectionsToReload release];
            }
                break;
        }
    }
        break;
    case(3): {
        switch([ indexPath indexAtPosition: 1]) {
            case (0): {
                if (UISegmentedControlNoSegment != [patientsSegmentedControl selectedSegmentIndex]) {
                    patientsSegmentedControl.selectedSegmentIndex = [patientsSegmentedControl selectedSegmentIndex];
                }
                else {
                    patientsSegmentedControl.selectedSegmentIndex = 0;
                }
                NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:3];
                //[self.tableView reloadData];
                [self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
                [tableView deselectRowAtIndexPath:indexPath animated:YES];
                [sectionsToReload release];
            }
                break;
            default: 
                break;
        }   
    }
        break;
    case(4): {
        switch([ indexPath indexAtPosition: 1]) {
            case (0): {
                if (UISegmentedControlNoSegment != [patientsStateSegmentedControl selectedSegmentIndex]) {
                    patientsStateSegmentedControl.selectedSegmentIndex = [patientsStateSegmentedControl selectedSegmentIndex];
                }
                else {
                    patientsStateSegmentedControl.selectedSegmentIndex = 0;
                }
                NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:4];
                //[self.tableView reloadData];
                [self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
                [tableView deselectRowAtIndexPath:indexPath animated:YES];
                [sectionsToReload release];
            }
                break;
        }   
    }
        break;
    case(5): {
        switch([ indexPath indexAtPosition: 1]) {
                case (0):
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://4030"]];
                break;
                case (1):
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://4030"]];
                break;
        }
    }
        break;
    default: break;
}}

最后我的numbersOfRowsInSections,可能是问题来源:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
switch (section) {
    case (0):
    {
        if (!positionControl.on) {
            return 1;
            break;
        }
        return 3;
    }
        break;
    case (1):
    {
        if (!photoControl.on) {
            return 1;
            break;
        }
        return 3;
    }
        break;
    case (2):
    {
        if (UISegmentedControlNoSegment == [dimensionSegmentedControl selectedSegmentIndex] || [dimensionSegmentedControl isMomentary]) {
            return 1;
            break;
        }
        return 2;
    }
        break;
    case (3):
    {
        if (UISegmentedControlNoSegment == [patientsSegmentedControl selectedSegmentIndex] || [patientsSegmentedControl isMomentary]) {
            return 1;
            break;
        }
        return 2;
    }
        break;
    case (4):
    {
        if (UISegmentedControlNoSegment == [patientsStateSegmentedControl selectedSegmentIndex] || [patientsStateSegmentedControl isMomentary]) {
            return 1;
            break;
        }
        return 2;
    }
        break;      
    case (5): {
        return 2;
    }
        break;
    case (6): {
        return 1;
    }
        break;
}
return 0;}

好吧,现在你可以看到我的代码,我会解释我的问题。当我处理UISwitches时,这些部分正确地重新加载......行出现并在前两个部分中消失,就像魅力一样。但是,当我从具有分段控件的部分单击单元格时,第一次一切正常,单元格显示分段控件,用户做出选择,分段控件消失,单行显示detailTextLabel中的用户选择。但是当我尝试点击另一行时,应用程序崩溃时出现以下异常:

  

***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第3节中的行数无效。更新后的现有部分中包含的行数(2)必须等于更新前该部分中包含的行数(1),加上或减去从该部分插入或删除的行数(插入0,删除0)。   2010-07-16 13:09:04.595 Barcodes [40421:207] Stack :(       35943515,       2535093513,       36027451,       1928964,       4228395,       4172781,       278302,       4188742,       4171908,       1425834,       35728064,       35724360,       43226645,       43226842,       3915695,       86847,       86454   )

两个部分之间的区别在于具有UISwitch的部分通过激活/停用交换机来显示和隐藏行,而其他部分通过选择行(didSelectRow ....)来显示和隐藏行。

任何帮助??

提前谢谢。

1 个答案:

答案 0 :(得分:0)

我的代码很好,如果我只是添加一个标志(BOOL)说每个分段控件必须是可见的。设置“YES”和“NO”这些标志并检查它们的值是否正常。