为了使用你提供的复杂数据源结构来构建多选列表,我们需要解析数据源并动态生成表格视图的内容。以下是具体的实现步骤和代码示例。

数据源结构

假设你的数据源结构如下:

{
  "data": [
    {
      "initial": "A",
      "data": [
        {
          "initial": "A",
          "id": 1,
          "brand_name": "APEX",
          "logo": "/static/logo/410.png"
        },
        {
          "initial": "A",
          "id": 2,
          "brand_name": "Aviar",
          "logo": "/static/logo/431.png"
        }
      ]
    },
    {
      "initial": "B",
      "data": [
        {
          "initial": "B",
          "id": 12,
          "brand_name": "北京",
          "logo": "/static/logo/27.png"
        },
        {
          "initial": "B",
          "id": 13,
          "brand_name": "标致",
          "logo": "/static/logo/13.png"
        }
      ]
    },
    {
      "initial": "C",
      "data": [
        {
          "initial": "C",
          "id": 16,
          "brand_name": "创维汽车",
          "logo": "/static/logo/400.png"
        },
        {
          "initial": "C",
          "id": 467,
          "brand_name": "超境汽车",
          "logo": "/static/logo/585.png"
        }
      ]
    },
    {
      "initial": "D",
      "data": [
        {
          "initial": "D",
          "id": 432,
          "brand_name": "东风奕派",
          "logo": "/static/logo/597.png"
        },
        {
          "initial": "D",
          "id": 433,
          "brand_name": "戴姆勒",
          "logo": "/static/logo/569.png"
        }
      ]
    }
  ]
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
实现步骤
  1. 解析数据源
  2. 构建表视图
  3. 管理选中状态
  4. 显示自定义的选中图片
代码示例
ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@end
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
ViewController.m
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray *data;
@property (nonatomic, strong) NSMutableDictionary *selectedItems;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 假设数据源是从服务器获取的,这里直接使用硬编码的 JSON 数据
    NSString *jsonString = @"{\"data\":[{\"initial\":\"A\",\"data\":[{\"initial\":\"A\",\"id\":1,\"brand_name\":\"APEX\",\"logo\":\"/static/logo/410.png\"},{\"initial\":\"A\",\"id\":2,\"brand_name\":\"Aviar\",\"logo\":\"/static/logo/431.png\"}]},{\"initial\":\"B\",\"data\":[{\"initial\":\"B\",\"id\":12,\"brand_name\":\"北京\",\"logo\":\"/static/logo/27.png\"},{\"initial\":\"B\",\"id\":13,\"brand_name\":\"标致\",\"logo\":\"/static/logo/13.png\"}]},{\"initial\":\"C\",\"data\":[{\"initial\":\"C\",\"id\":16,\"brand_name\":\"创维汽车\",\"logo\":\"/static/logo/400.png\"},{\"initial\":\"C\",\"id\":467,\"brand_name\":\"超境汽车\",\"logo\":\"/static/logo/585.png\"}]},{\"initial\":\"D\",\"data\":[{\"initial\":\"D\",\"id\":432,\"brand_name\":\"东风奕派\",\"logo\":\"/static/logo/597.png\"},{\"initial\":\"D\",\"id\":433,\"brand_name\":\"戴姆勒\",\"logo\":\"/static/logo/569.png\"}]}]}";
    
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
    self.data = jsonDict[@"data"];
    
    self.selectedItems = [NSMutableDictionary dictionary];
    
    // 初始化 tableView
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];
}

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.data.count;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return self.data[section][@"initial"];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.data[section][@"data"] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        
        // 添加自定义选中图片
        UIImageView *checkmarkImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
        checkmarkImageView.tag = 100; // 设置tag以便以后查找
        cell.accessoryView = checkmarkImageView;
    }
    
    NSDictionary *sectionData = self.data[indexPath.section];
    NSArray *rowData = sectionData[@"data"];
    NSDictionary *item = rowData[indexPath.row];
    cell.textLabel.text = item[@"brand_name"];
    
    // 设置自定义选中图片
    UIImageView *checkmarkImageView = (UIImageView *)cell.accessoryView;
    if ([self isSelectedItemAtIndexPath:indexPath]) {
        checkmarkImageView.image = [UIImage imageNamed:@"checkbox_selected"];
    } else {
        checkmarkImageView.image = [UIImage imageNamed:@"checkbox_unselected"];
    }
    
    return cell;
}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self toggleSelectionAtIndexPath:indexPath];
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}

#pragma mark - 选择逻辑

- (void)toggleSelectionAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary *sectionData = self.data[indexPath.section];
    NSString *key = sectionData[@"initial"];
    NSArray *rowData = sectionData[@"data"];
    NSDictionary *item = rowData[indexPath.row];
    NSString *itemId = item[@"id"];
    
    NSMutableArray *selectedItemsInSection = self.selectedItems[key];
    if (!selectedItemsInSection) {
        selectedItemsInSection = [NSMutableArray array];
        self.selectedItems[key] = selectedItemsInSection;
    }
    
    if ([selectedItemsInSection containsObject:itemId]) {
        [selectedItemsInSection removeObject:itemId];
    } else {
        [selectedItemsInSection addObject:itemId];
    }
}

- (BOOL)isSelectedItemAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary *sectionData = self.data[indexPath.section];
    NSString *key = sectionData[@"initial"];
    NSArray *rowData = sectionData[@"data"];
    NSDictionary *item = rowData[indexPath.row];
    NSString *itemId = item[@"id"];
    NSArray *selectedItemsInSection = self.selectedItems[key];
    return [selectedItemsInSection containsObject:itemId];
}

@end
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
解释
  1. 解析数据源:在 viewDidLoad 方法中解析 JSON 数据,并将其存储在 self.data 中。
  2. 表视图数据源方法
  • numberOfSectionsInTableView:返回数据的节数。
  • titleForHeaderInSection:返回每节的标题。
  • numberOfRowsInSection:返回每节的行数。
  • cellForRowAtIndexPath:配置每个单元格的内容和自定义选中图片。
  1. 表视图委托方法
  • didSelectRowAtIndexPath:处理单元格点击事件,切换选中状态并刷新单元格。
  1. 选择逻辑
  • toggleSelectionAtIndexPath:切换选中状态,将选中项的 ID 添加到或从 selectedItems 中移除。
  • isSelectedItemAtIndexPath:检查某个项目是否被选中,通过查看 selectedItems 中是否包含该项目的 ID 来实现。

通过这种方式,可以在 UITableViewCell 上自定义一个图片用来标记选中效果,并实现多选功能。你需要提供 checkbox_selectedcheckbox_unselected 两个图像文件,以实现复选框的选中和未选中状态。

仅做记录!