UITableView每个部分选择一行

时间:2012-12-20 03:50:02

标签: ios objective-c uitableview

我想做出这样的选择 enter image description here

如何更改

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath  

委托方法按照我的要求工作。

7 个答案:

答案 0 :(得分:3)

为什么这么复杂?在用户选择新的单元格之前,只需取消选择同一部分的所有单元格。

首先允许为UITableView进行多项选择。然后实现这个委托方法:

Swift 3版本:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
{
    for vcip in tableView.indexPathsForSelectedRows ?? [] {
        if vcip.section == indexPath.section && vcip.item != indexPath.item {
            tableView.deselectRow(at: vcip, animated: false)
        }
    }
    return indexPath
}

答案 1 :(得分:2)

  1. 在视图控制器中保留一个名为selectedRow的属性,该属性表示tableview的indexPath,表示表格部分中的已检查项目。

  2. 如果单元格的-tableView:cellForRowAtIndexPath:等于{{{ 1}} indexpath值。否则,请将其设置为accessoryType

  3. 在视图控制器的cell委托方法中,将UITableViewCellAccessoryCheckmark值设置为所选的indexPath,例如:selectedRow

答案 2 :(得分:2)

这不是一个好的解决方案。 使用NSMutableArray存储选定的部分。

NSMutableArray *selectedSections; //instance variable

selectedSections= [[NSMutableArray alloc] init];   //in viewDidLoad

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   NSNumber *section = [NSNumber numberWithInt:indexPath.section];
   if([selectedSections containsObject:section]
      return nil;
   else
   {
      [selectedSections addObject:section];
      return indexPath;
   }
}

当你取消选择一行时,在那里写下面的代码:

[selectedSections removeObject:[NSNumber numberWithInt:indexPath.section]];

答案 3 :(得分:2)

LimeRed has a great answer elsewhere in this thread, but it is not complete. The key issue is that the OP needs to have the accessory checkmark removed. Simply calling deselectRow will not remove the checkmark. Per the documentation, deselectRow does not call the delegate method tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) where the removal of the checkmark code might be located. Therefore you need handle this removal as part of the code that LimeRed wrote.

Here is a more complete implementation that removes the accessory checkmark again based on LimeRed's solution:

    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
    {
        for path in tableView.indexPathsForSelectedRows ?? []
        {
            if path.section == indexPath.section && path.item != indexPath.item
            {
                let cell = tableView.cellForRow(at: path)
                cell?.accessoryType = UITableViewCellAccessoryType.none
                tableView.deselectRow(at: path, animated: false)
            }
        }

        return indexPath
    }

答案 4 :(得分:1)

尝试这样,

在.h

@property (nonatomic, retain) NSIndexPath *checkedIndexPath;

在.m

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ 


    if(indexPath.section==0)
    {

        // to check and Uncheck the row
        if(self.checkedIndexPath)
        {
            UITableViewCell* uncheckCell = [tableView1
                                            cellForRowAtIndexPath:self.checkedIndexPath];
            uncheckCell.accessoryType = UITableViewCellAccessoryNone;
        }
        if([self.checkedIndexPath isEqual:indexPath])
        {
            self.checkedIndexPath = nil;
        }
        else
        {
            UITableViewCell* cell = [tableView1 cellForRowAtIndexPath:indexPath];
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            self.checkedIndexPath = indexPath;
        }

    }
}

答案 5 :(得分:0)

经过大量修改后,我已经到了这个

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath];


if(indexPath.section == 0)
{
    if([section1Rows count] == 0)
    {
        [section1Rows addObject:[NSNumber numberWithInt:indexPath.row]];
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    else
    {
        [section1Rows removeObjectAtIndex:0];

        for (UITableViewCell *cell in [tabview visibleCells]) {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }

        [section1Rows addObject:[NSNumber numberWithInt:indexPath.row]];
        NSLog(@"%@",section1Rows);
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
}

if(indexPath.section == 1)
{
    if([section2Rows count] == 0)
    {
        [section2Rows addObject:[NSNumber numberWithInt:indexPath.row]];
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    else
    {
        [section2Rows removeObjectAtIndex:0];

        for (UITableViewCell *cell in [tabview visibleCells]) {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }

        [section2Rows addObject:[NSNumber numberWithInt:indexPath.row]];
        NSLog(@"%@",section2Rows);
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
}

if(indexPath.section == 2)
{
    if([section3Rows count] == 0)
    {
        [section3Rows addObject:[NSNumber numberWithInt:indexPath.row]];
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    else
    {
        [section3Rows removeObjectAtIndex:0];

        for (UITableViewCell *cell in [tabview visibleCells]) {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }

        [section3Rows addObject:[NSNumber numberWithInt:indexPath.row]];
        NSLog(@"%@",section3Rows);
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
}


}

我会逐步解释这个问题, 我在3个部分中选择了一行,如果我在任何部分再次选择一行......那么一切都变得混乱。如何取消选择先前选定的行并突出显示当时选定的行?

感谢。

答案 6 :(得分:0)

这个将是ViewController.h

@interface ViewController : UITableViewController
{
    NSMutableArray *list;
    NSMutableArray *sectionList;

    NSIndexPath *oldIndexPath0;
    int row0;
    NSIndexPath *oldIndexPath1;
    int row1;
    NSIndexPath *oldIndexPath2;
    int row2;
    NSIndexPath *oldIndexPath3;
    int row3;

    NSString *othersString;
    NSString *timeString;
    NSString *pRoomString;
    NSString *parkingString;
    NSString *smokingString;

    NSString *select0;
    NSString *select1;
    NSString *select2;
    NSString *select3;
}
@end

这是一个ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated
{
    // initial row by 100;
    row0 = 100;
    row1 = 100;
    row2 = 100;
    row3 = 100;

    // initial strings by @”"
    othersString = [NSString stringWithFormat:@""];
    timeString = [NSString stringWithFormat:@""];
    pRoomString = [NSString stringWithFormat:@""];
    parkingString = [NSString stringWithFormat:@""];
    smokingString = [NSString stringWithFormat:@""];

    select0 = @"";
    select1 = @"";
    select2 = @"";
    select3 = @"";

    // Get row index
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/rowString.txt"];
    NSData *rowData = [fileManager  contentsAtPath:fileName];
    // From NSData to NSString
    NSString *rowString = [[NSString alloc] initWithData:rowData encoding:NSUTF8StringEncoding];
    if (rowString) {
        // spit row string
        NSArray *rowArray = [rowString componentsSeparatedByString:@":"];
        for (int i=0; i<[rowArray count]; i++) {
            NSString *indexVal = [rowArray objectAtIndex:i];
            if ([indexVal length] != 0) {
                // set row value
                if (i == 0) {
                    NSString *row0Str = [rowArray objectAtIndex:0];
                    row0 = [row0Str intValue];
                }
                if (i == 1) {
                    NSString *row1Str = [rowArray objectAtIndex:1];
                    row1 = [row1Str intValue];
                }
                if (i == 2) {
                    NSString *row2Str = [rowArray objectAtIndex:2];
                    row2 = [row2Str intValue];
                }
                if (i == 3) {
                    NSString *row3Str = [rowArray objectAtIndex:3];
                    row3 = [row3Str intValue];
                }
            }
        }
    }
    // Update the view with current data before it is displayed.
    [super viewWillAppear:animated];

    //Initialize the array.
    list = [[NSMutableArray alloc] initWithCapacity:0];
    sectionList = [[NSMutableArray alloc] initWithCapacity:0];

    // section header
    NSArray *sectionHeaderArray = [NSArray arrayWithObjects:@"01",@"02",@"03",@"04", nil];
    NSDictionary *sectionHeaderDic = [NSDictionary dictionaryWithObject:sectionHeaderArray forKey:@"section"];
    [sectionList addObject:sectionHeaderDic];
    // time list
    NSArray *timeArray = [NSArray arrayWithObjects:@"time 01",@"time 01",@"time 01", nil];
    NSDictionary *timeDic = [NSDictionary dictionaryWithObject:timeArray forKey:@"time"];
    // private room
    NSArray *pRoomArray = [NSArray arrayWithObjects:@"room 01",@"room 02", nil];
    NSDictionary *pRoomDic = [NSDictionary dictionaryWithObject:pRoomArray forKey:@"pRoom"];
    // parking
    NSArray *parkingArray = [NSArray arrayWithObjects:@"park 01",@"park 02",@"park 03", nil];
    NSDictionary *parkingDic = [NSDictionary dictionaryWithObject:parkingArray forKey:@"parking"];
    // smoking
    NSArray *smokingArray = [NSArray arrayWithObjects:@"smoke 01",@"smoke 02",@"smoke 03", nil];
    NSDictionary *smokingDic = [NSDictionary dictionaryWithObject:smokingArray forKey:@"smoking"];
    // add all dictionary to list
    [list addObject:timeDic];
    [list addObject:pRoomDic];
    [list addObject:parkingDic];
    [list addObject:smokingDic];
    // Scroll the table view to the top before it appears
    [self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    //Number of section
    return [list count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    //Get the dictionary object
    NSDictionary *dictionary = [list objectAtIndex:section];
    NSArray *array;
    switch (section) {
        case 0:
            // time array
            array = [dictionary objectForKey:@"time"];
            break;
        case 1:
            // pRoom array
            array = [dictionary objectForKey:@"pRoom"];
            break;
        case 2:
            // parking array
            array = [dictionary objectForKey:@"parking"];
            break;
        case 3:
            // smoking array
            array = [dictionary objectForKey:@"smoking"];
            break;
        default:
            break;
    }
    //Number of rows
    return [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Budget";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        UITableViewCellStyleSubtitle;
    }
    //Get the dictionary object
    NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
    NSArray *array;
    switch (indexPath.section) {
        case 0:
            // time array
            array = [dictionary objectForKey:@"time"];
            if (indexPath.row == row0 ) {
                cell.accessoryType=UITableViewCellAccessoryCheckmark;
            }else{
                cell.accessoryType = UITableViewCellAccessoryNone;
            }
            break;
        case 1:
            // pRoom array
            array = [dictionary objectForKey:@"pRoom"];
            if (indexPath.row == row1) {
                cell.accessoryType=UITableViewCellAccessoryCheckmark;
            }else{
                cell.accessoryType = UITableViewCellAccessoryNone;
            }
            break;
        case 2:
            // parking array
            array = [dictionary objectForKey:@"parking"];
            if (indexPath.row == row2) {
                cell.accessoryType=UITableViewCellAccessoryCheckmark;
            }else{
                cell.accessoryType = UITableViewCellAccessoryNone;
            }
            break;
        case 3:
            // smoking array
            array = [dictionary objectForKey:@"smoking"];
            if (indexPath.row == row3) {
                cell.accessoryType=UITableViewCellAccessoryCheckmark;
            }else{
                cell.accessoryType = UITableViewCellAccessoryNone;
            }
            break;
        default:
            break;
    }
    cell.textLabel.text = [array objectAtIndex:indexPath.row];
    NSLog(@"index cell");
    return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    NSString *title = nil;
    //Get the dictionary object
    NSDictionary *dictionary = [sectionList objectAtIndex:0];
    NSArray *array = [dictionary objectForKey:@"section"];
    title = [array objectAtIndex:section];
    return title;
}

#pragma mark -
#pragma mark Table view selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
    switch(indexPath.section)
    {
        case 0:
        {
            UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
            if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                cell1.accessoryType = UITableViewCellAccessoryNone;
                row0 = 100;
                timeString = @"";
            }else {
                NSIndexPath *SIndexPath0 = [NSIndexPath indexPathForRow:row0 inSection:0];
                if ([[tableView cellForRowAtIndexPath:SIndexPath0 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                    [[tableView cellForRowAtIndexPath:SIndexPath0] setAccessoryType:UITableViewCellAccessoryNone];
                }
                if (oldIndexPath0 == nil) {
                    oldIndexPath0 = indexPath;
                }
                UITableViewCell *cell2 = nil;
                if (oldIndexPath0 != indexPath) {
                    cell2 = [tableView cellForRowAtIndexPath:oldIndexPath0];
                }
                cell1.accessoryType = UITableViewCellAccessoryCheckmark;
                if (cell2) {
                    cell2.accessoryType = UITableViewCellAccessoryNone;
                }
                //Get the dictionary object
                NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
                NSArray *array = [dictionary objectForKey:@"time"];
                timeString = [array objectAtIndex:indexPath.row];
                row0 = indexPath.row;
                oldIndexPath0 = nil;
            }
            select0 = @"marked";
            break;
        }
        case 1:
        {
            UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
            if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                cell1.accessoryType = UITableViewCellAccessoryNone;
                row1 = 100;
                pRoomString = @"";
            }else {
                NSIndexPath *SIndexPath1 = [NSIndexPath indexPathForRow:row1 inSection:1];
                if ([[tableView cellForRowAtIndexPath:SIndexPath1 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                    [[tableView cellForRowAtIndexPath:SIndexPath1] setAccessoryType:UITableViewCellAccessoryNone];
                }
                if (oldIndexPath1 == nil) {
                    oldIndexPath1 = indexPath;
                }
                UITableViewCell *cell2 = nil;
                if (oldIndexPath1 != indexPath) {
                    cell2 = [tableView cellForRowAtIndexPath:oldIndexPath1];
                }
                cell1.accessoryType = UITableViewCellAccessoryCheckmark;
                if (cell2) {
                    cell2.accessoryType = UITableViewCellAccessoryNone;
                }
                //Get the dictionary object
                NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
                NSArray *array = [dictionary objectForKey:@"pRoom"];
                pRoomString = [array objectAtIndex:indexPath.row];
                row1 = indexPath.row;
                oldIndexPath1 = nil;
            }
            select1 = @"marked";
            break;
        }
        case 2:
        {
            UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
            if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                cell1.accessoryType = UITableViewCellAccessoryNone;
                row2 = 100;
                parkingString = @"";
            }else {
                NSIndexPath *SIndexPath2 = [NSIndexPath indexPathForRow:row2 inSection:2];
                if ([[tableView cellForRowAtIndexPath:SIndexPath2 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                    [[tableView cellForRowAtIndexPath:SIndexPath2] setAccessoryType:UITableViewCellAccessoryNone];
                }
                if (oldIndexPath2 == nil) {
                    oldIndexPath2 = indexPath;
                }
                UITableViewCell *cell2 = nil;
                if (oldIndexPath2 != indexPath) {
                    cell2 = [tableView cellForRowAtIndexPath:oldIndexPath2];
                }
                cell1.accessoryType = UITableViewCellAccessoryCheckmark;
                if (cell2) {
                    cell2.accessoryType = UITableViewCellAccessoryNone;
                }
                //Get the dictionary object
                NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
                NSArray *array = [dictionary objectForKey:@"parking"];
                parkingString = [array objectAtIndex:indexPath.row];
                row2 = indexPath.row;
                oldIndexPath2 = nil;
            }
            select2 = @"marked";
            break;
        }
        case 3:
        {
            UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
            if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                cell1.accessoryType = UITableViewCellAccessoryNone;
                row3 = 100;
                smokingString = @"";
            }else {
                NSIndexPath *SIndexPath3 = [NSIndexPath indexPathForRow:row3 inSection:3];
                if ([[tableView cellForRowAtIndexPath:SIndexPath3 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
                    [[tableView cellForRowAtIndexPath:SIndexPath3] setAccessoryType:UITableViewCellAccessoryNone];
                }
                if (oldIndexPath3 == nil) {
                    oldIndexPath3 = indexPath;
                }
                UITableViewCell *cell2 = nil;
                if (oldIndexPath3 != indexPath) {
                    cell2 = [tableView cellForRowAtIndexPath:oldIndexPath3];
                }
                cell1.accessoryType = UITableViewCellAccessoryCheckmark;
                if (cell2) {
                    cell2.accessoryType = UITableViewCellAccessoryNone;
                }
                //Get the dictionary object
                NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
                NSArray *array = [dictionary objectForKey:@"smoking"];
                smokingString = [array objectAtIndex:indexPath.row];
                row3 = indexPath.row;
                oldIndexPath3 = nil;
            }
            select3 = @"marked";
            break;
        }
        default:
            break;
    }
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    // Cancle button and add an event handler
    self.navigationItem.leftBarButtonItem =
    [[UIBarButtonItem alloc] initWithTitle:@"Cancle"
                                     style:UIBarButtonSystemItemCancel
                                    target:self
                                    action:@selector(handleCancle:)];
    // Cancle button and add an event handler
    self.navigationItem.rightBarButtonItem =
    [[UIBarButtonItem alloc] initWithTitle:@"Use"
                                     style:UIBarButtonItemStyleBordered
                                    target:self
                                    action:@selector(handleUse:)];
}
- (void) handleCancle:(id)sender
{
    // pop the controller
    [self.navigationController popViewControllerAnimated:YES];
}
- (void) handleUse:(id)sender{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *fileName;
    // Get row index value
    fileName = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/othersString.txt"];
    NSData *rowValData = [fileManager   contentsAtPath:fileName];
    // From NSData to NSString
    NSString *rowValString = [[NSString alloc] initWithData:rowValData encoding:NSUTF8StringEncoding];
    NSString *oldTimeString = @"";
    NSString *oldpRoomString = @"";
    NSString *oldParkingString = @"";
    NSString *oldSmokingString = @"";
    if (rowValString) {
        // spit row string
        NSArray *rowValArray = [rowValString componentsSeparatedByString:@":"];
        for (int i=0; i<[rowValArray count]; i++) {
            if ([rowValArray objectAtIndex:i] != @"") {
                // set row value
                if (i == 0 ) {
                    oldTimeString = [rowValArray objectAtIndex:0];
                }
                if (i == 1 ) {
                    oldpRoomString = [rowValArray objectAtIndex:1];
                }
                if (i == 2 ) {
                    oldParkingString = [rowValArray objectAtIndex:2];
                }
                if (i == 3) {
                    oldSmokingString = [rowValArray objectAtIndex:3];
                }
            }
        }
    }
    if (select0 == @"") {
        timeString = oldTimeString;
    }
    if (select1 == @"") {
        pRoomString = oldpRoomString;
    }
    if (select2 == @"") {
        parkingString = oldParkingString;
    }
    if (select3 == @"") {
        smokingString = oldSmokingString;
    }
    // make othersString string
    othersString = [NSString stringWithFormat:@"%@:%@:%@:%@", timeString, pRoomString, parkingString, smokingString];
    // write othersString to othersString.txt file
    fileName= [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/othersString.txt"];
    NSData *othersData = [othersString dataUsingEncoding:NSUTF8StringEncoding];
    [fileManager createFileAtPath:fileName contents:othersData attributes:nil];
    // make row data in string
    NSString *rowString = [NSString stringWithFormat:@"%i:%i:%i:%i", row0,row1,row2,row3];
    // write othersString to othersString.txt file
    fileName = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/rowString.txt"];
    NSData *rowData = [rowString dataUsingEncoding:NSUTF8StringEncoding];
    [fileManager createFileAtPath:fileName contents:rowData attributes:nil];
    // pop the controller
    [self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}
- (void)dealloc {
    [super dealloc];
    [list release];
}
@end

从这个post得到了这些东西,因为这是日语我改变了它。感谢作者。