【问题标题】:UITableViewCell - check mark one row per sectionUITableViewCell - 选中每个部分一行
【发布时间】:2014-10-14 19:53:03
【问题描述】:

我有 2 个部分和 3 行,如下所示:

  1. 搜索距离

    • 250 英尺

    • 1000 英尺

    • 4000 英尺

  2. 地图类型

    • 标准

    • 卫星

    • 混合

我希望每个部分的一行有一个复选标记,但我当前的代码将取消选中整个表格视图的所有可见单元格,并留下一个选中的行带有复选标记。换句话说,我将为整个表格(2 个部分)设置一个复选标记。在这里,我发布了我的整个代码。我用谷歌搜索了很多,但似乎没有一个可以解决我的问题。任何人,请帮助纠正我的代码。提前致谢。

#import "PAWSettingsViewController.h"
#import "PAWAppDelegate.h"
#import <Parse/Parse.h>

@interface PAWSettingsViewController ()

- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath;
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath;


- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath;
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath;

@property (nonatomic, assign) CLLocationAccuracy filterDistance;

@end



typedef enum {
    kPAWSettingsTableViewDistance = 0,
    kPAWSettingsTableViewMaptype,
    kPAWSettingsTableViewNumberOfSections
} kPAWSettingsTableViewSections;


typedef enum {
    kPAWSettingsTableViewDistanceSection250FeetRow = 0,
    kPAWSettingsTableViewDistanceSection1000FeetRow,
    kPAWSettingsTableViewDistanceSection4000FeetRow,
    kPAWSettingsTableViewDistanceNumberOfRows
} kPAWSettingsTableViewDistanceSectionRows;

typedef enum {
    kPAWSettingsTableViewMaptypeSectionStandardRow = 0,
    kPAWSettingsTableViewMaptypeSectionSatelliteRow,
    kPAWSettingsTableViewMaptypeSectionHybridRow,
    kPAWSettingsTableViewMaptypeNumberOfRows
} kPAWSettingsTableViewMaptypeSectionRows;


@implementation PAWSettingsViewController

@synthesize tableView;
@synthesize filterDistance;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        self.filterDistance = appDelegate.filterDistance;
    }
    return self;
}


#pragma mark - Custom setters

// Always fault our filter distance through to the app delegate. We just cache it locally because it's used in the tableview's cells.
- (void)setFilterDistance:(CLLocationAccuracy)aFilterDistance {
    PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    appDelegate.filterDistance = aFilterDistance;
    filterDistance = aFilterDistance;
}

#pragma mark - View lifecycle

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Private helper methods

- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath {
    NSString *cellText = nil;
    switch (indexPath.row) {
        case kPAWSettingsTableViewDistanceSection250FeetRow:
            cellText = @"250 feet";
            break;
        case kPAWSettingsTableViewDistanceSection1000FeetRow:
            cellText = @"1000 feet";
            break;
        case kPAWSettingsTableViewDistanceSection4000FeetRow:
            cellText = @"4000 feet";
            break;
        case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
        default:
            cellText = @"The universe";
            break;
    }
    return cellText;
}

- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath {
    PAWLocationAccuracy distance = 0.0;
    switch (indexPath.row) {
        case kPAWSettingsTableViewDistanceSection250FeetRow:
            distance = 250;
            break;
        case kPAWSettingsTableViewDistanceSection1000FeetRow:
            distance = 1000;
            break;
        case kPAWSettingsTableViewDistanceSection4000FeetRow:
            distance = 4000;
            break;
        case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
        default:
            distance = 10000 * kPAWFeetToMiles;
            break;
    }

    return distance;
}

- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath {
    NSString *cellText = nil;
    switch (indexPath.row) {
        case kPAWSettingsTableViewMaptypeSectionStandardRow:
            cellText = @"Standard";
            break;
        case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
            cellText = @"Satellite";
            break;
        case kPAWSettingsTableViewMaptypeSectionHybridRow:
            cellText = @"Hybrid";
            break;
        case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
        default:
            cellText = @"?";
            break;
    }
    return cellText;
}

- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath {
    PAWMaptypeSelect maptype = nil;
    switch (indexPath.row) {
        case kPAWSettingsTableViewMaptypeSectionStandardRow:
            maptype = @"Standard";
            break;
        case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
            maptype = @"Satellite";
            break;
        case kPAWSettingsTableViewMaptypeSectionHybridRow:
            maptype = @"Hybrid";
            break;
        case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
        default:
            maptype = nil;
            break;
    }

    return maptype;
}

#pragma mark - UINavigationBar-based actions

- (IBAction)done:(id)sender {
    [self.presentingViewController dismissModalViewControllerAnimated:YES];
}

#pragma mark - UITableViewDataSource methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return kPAWSettingsTableViewNumberOfSections;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    switch ((kPAWSettingsTableViewSections)section) {
        case kPAWSettingsTableViewDistance:
            return kPAWSettingsTableViewDistanceNumberOfRows;
            break;

        case kPAWSettingsTableViewMaptype:
            return kPAWSettingsTableViewMaptypeNumberOfRows;
            break;

        case kPAWSettingsTableViewNumberOfSections:
            return 2;
            break;
    };
}

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"SettingsTableView";
    if (indexPath.section == kPAWSettingsTableViewDistance) {
        UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
        if ( cell == nil )
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];

        }

        // Configure the cell.
        cell.textLabel.text = [self distanceLabelForCell:indexPath];

        if (self.filterDistance == 0.0) {
            NSLog(@"We have a zero filter distance!");
        }

        PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
        PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
        if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        } else {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }


        return cell;
    }

    else if (indexPath.section == kPAWSettingsTableViewMaptype){
        UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
        if ( cell == nil )
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
        }

        // Configure the cell.
        cell.textLabel.text = [self maptypeLabelForCell:indexPath];


        return cell;

    }


    else {
        return nil;
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    switch ((kPAWSettingsTableViewSections)section) {
        case kPAWSettingsTableViewDistance:
            return @"Search Distance";
            break;

        case kPAWSettingsTableViewMaptype:
            return @"Map Type";
            break;

        case kPAWSettingsTableViewNumberOfSections:
            return @"";
            break;
    }
}

#pragma mark - UITableViewDelegate methods

// Called after the user changes the selection.
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


    if (indexPath.section == kPAWSettingsTableViewDistance) {
        [aTableView deselectRowAtIndexPath:indexPath animated:YES];



        // if we were already selected, bail and save some work.
        UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
            return;
        }


        // uncheck all visible cells.
        for (UITableViewCell *cell in [aTableView visibleCells]) {
            if (cell.accessoryType != UITableViewCellAccessoryNone) {
                cell.accessoryType = UITableViewCellAccessoryNone;
            }
        }


        selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;

        PAWLocationAccuracy distanceForCellInFeet = [self distanceForCell:indexPath];
        self.filterDistance = distanceForCellInFeet * kPAWFeetToMeters;
    }



    else if (indexPath.section == kPAWSettingsTableViewMaptype){
        [aTableView deselectRowAtIndexPath:indexPath animated:YES];

        // if we were already selected, bail and save some work.
        UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
            return;
        }

        // uncheck all visible cells.
        for (UITableViewCell *cell in [aTableView visibleCells]) {
            if (cell.accessoryType != UITableViewCellAccessoryNone) {
                cell.accessoryType = UITableViewCellAccessoryNone;
            }
        }

        selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;

        PAWMaptypeSelect maptypeForCell = [self maptypeForCell:indexPath];

    }

}


@end

【问题讨论】:

  • 你可以有2个静态部分还是动态的?
  • @SanitLee 你能解决你的问题吗?
  • 还没有,我刚刚将评论添加回@BHASKAR

标签: ios objective-c uitableview checkmark accessorytype


【解决方案1】:

你有这个错误

//取消选中所有可见单元格。

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

这里的 for 循环取消选择所有单元格。您还必须检查 if 循环中的部分

你可以像这样为你的单元格设置标签

 cell.tag = indexPath.section;

如果条件为则在for循环中

    for (UITableViewCell *cell in [aTableView visibleCells]) {
        if (cell.accessoryType != UITableViewCellAccessoryNone && cell.tag == indexPath.section) {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

【讨论】:

  • 由于我不完全了解标签的工作原理,您将如何在我的代码中实现 cell.tag?我看到的是 'FOR (UITableViewCell *cell in [aTableView visibleCells])' 中的条件需要纠正,但是如何纠正?我非常喜欢你的想法,但不知道如何准确地实现它。当然,我已经修补过它,但尚未成功。
  • - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath add cell.tag = indexPath.section; after // 配置单元格。行并用这个改变你的for循环
  • 我还没有足够的声望来投票。我很新。或者我还有什么可以弥补的? :)
  • 不不不,如果你支持它,那么其他人就可以知道它的作品。没关系。
  • 我为此创建了一个后续问题。这是链接:stackoverflow.com/questions/25459035/…希望你能回答。谢谢。
【解决方案2】:

您的代码中的问题是您只需通过以下方法替换第 0 部分的选中行,您就可以解决您的问题。

     - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"SettingsTableView";
if (indexPath.section == kPAWSettingsTableViewDistance) {
    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
    if ( cell == nil )
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];

    }

    // Configure the cell.
    cell.textLabel.text = [self distanceLabelForCell:indexPath];

    if (self.filterDistance == 0.0) {
        NSLog(@"We have a zero filter distance!");
    }

    PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
    PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
    if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }


    return cell;
}

else if (indexPath.section == kPAWSettingsTableViewMaptype){
    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
    if ( cell == nil )
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
    }

    // Configure the cell.
    cell.textLabel.text = [self maptypeLabelForCell:indexPath];

    PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
    PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
    if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    return cell;

}


else {
    return nil;
}
}

【讨论】:

  • 你是对的,但是section1(地图类型)中的复选标记方式与section0(距离)不同。我希望将“地图类型 - 标准”检查为默认值,用户稍后选择的任何选项都可以保存并传递到另一个视图控制器,该控制器包含地图视图以根据所选地图类型显示。
  • 我为此创建了一个新问题,因为它是一个不同的问题。这是链接:stackoverflow.com/questions/25459035/…
【解决方案3】:

目前我发现了以下错误

  1. 您没有保存为地图类型选择的单元格。
  2. 检查单元格的方式不正确。
  3. 在 switch 中你不必在 return 语句之后使用 break
  4. case kPAWSettingsTableViewNumberOfSections: 你应该返回kPAWSettingsTableViewNumberOfSections

前两个缺陷导致许多样板代码。我认为您应该为每个被选为附加@property 的部分存储NSIndexPath。您可以在tableView:didSelectRowAtIndexPath: 中进行操作,而不是取消选中全部并选中已点击:

  1. 确定应该选择哪一个。
  2. 存储您的 selectedIndexPath 的本地旧值。
  3. selectedIndexPath 属性更改为新属性。
  4. 重新加载两行。

然后你必须在tableView:cellForRowAtIndexPath:中添加以下代码:

if (indexPath.row == self.selectedIndexPath.row && indexPath.section == self.selectedIndexPath.section) {
    // Change to checkmark.
} else { 
   // Change to not checked.
}

我在自己的项目中使用非常相似的方式来勾选单元格。我希望下面的代码也能帮助你理解我解决问题的方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (/*condition*/) {
        [...]
    }
    else if (/*checkmark section*/) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CheckmarkCellId forIndexPath:indexPath];
        cell.textLabel.text = [self labelForRow:indexPath.row];
        cell.accessoryType = (indexPath.row == [self defaultAgglomerationIndex]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
        cell.imageView.image = (indexPath.row == [self selectedAgglomerationIndex]) ? [UIImage imageNamed:@"icoMap"] : [UIImage imageNamed:@"region"];
        return cell;
    }
    else if (/*Another condition */) {
        [...]
    }
    return nil;
}

tableView:didSelectRowAtIndexPath: 中的基本代码(我重新加载整个部分)

self.selectedIndex = indexPath;
NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
[self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone];

【讨论】:

    【解决方案4】:

    试试这个,对我来说效果很好:

    -变量:

    @property NSInteger checkedCellRow;
    @property NSInteger checkedCellSection;
    

    -功能:

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (checkedCellSection == indexPath.section)
    {
    if (checkedCellRow == indexPath.row)
    {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else
    {
    cell.accessoryType = UITableViewCellAccessoryNone;
    }
    }
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
    checkedCellRow = indexPath.row;
    checkedCellSection = indexPath.section;
    [myTable reloadData];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 2014-09-01
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多