为 UITableView 标头创建数组

Posted

技术标签:

【中文标题】为 UITableView 标头创建数组【英文标题】:Create array for UITableView headers 【发布时间】:2014-02-15 12:49:01 【问题描述】:

在我的 iPhone 应用程序中,我想显示一个带有部分标题的表格视图。 我有一个这样的数据源(示例)

(
     date : 12-10-2014  rowdata:abc,
     date : 12-10-2014  rowdata:pqr,
     date : 12-10-2014  rowdata:xyz,
     date : 13-10-2014  rowdata:123,
     date : 13-10-2014  rowdata:780,
     date : 14-10-2014  rowdata:tuv,
)

我想将部分标题显示为日期 - 并且必须像这样在其中显示行数据 (只需将其视为表格视图的格式 - 日期是标题视图和行下方)

12-10-2014
   abc
   pqr
   xyz
13-10-2014
   123
   780
13-10-2014
   tuv

请告诉我如何使用我的数据源更改或创建新数组的逻辑,我很清楚使用分段的表格视图和标题视图。

我可以为标题视图创建一个带有日期的单独数组,但是如何在每个部分下显示行数据,因为在每个部分中,行都从索引 0 开始。

【问题讨论】:

你需要分解你的问题。您需要解析字符串的帮助吗?创建标题?填充表格视图? 请看我编辑的问题 您可以查看我的答案以获得详细的回复:) 我强烈建议您在这种情况下使用该方法。 【参考方案1】:

您基本上是在问如何通过 date 键对您的 rowdata 数据进行分类。

简单。您需要执行以下操作:

    为您的数据对创建数据模型,以便更好地填充您的表并存储在数组中:) 创建一个字典,将 date 存储为键 - 您可以将它们想象为类别 - 并将行数据作为对象存储在每个类别的数组中。

第 1 步: 创建您的自定义数据模型,使数据管理更轻松、更清晰。 创建两个名为rowDataModel.hrowDataModel.m 的新文件。它们将是NSObject 类的子类。

这就是您的.h 文件的样子:

#import <Foundation/Foundation.h>

@interface rowDataModel : NSObject
@property (nonatomic, retain) NSString * rowDataDate;
@property (nonatomic, retain) NSString * rowDataInformation;

-(id)initWithJSONData:(NSDictionary*)data;
@end

在您的.m 文件中,您将拥有以下内容:

#import "rowDataModel.h"

@implementation rowDataModel
@synthesize rowDataDate;
@synthesize rowDataInformation;

-(id)initWithJSONData:(NSDictionary*)data

    if (self = [super init]) 
        self.rowDataDate = [data objectForKey:@"date"];
        self.rowDataInformation = [data objectForKey:@"rowdata"];

    
    return self;

@end

我们这样做是因为这将包含易于使用的容器。它也是管理自定义 json 对象的好方法。

第 2 步 现在在您将填充数据库并对数据进行分类的视图控制器中,确保导入您的自定义 rowDataModel.h 文件

NSMutableDictionary *myData = [[NSMutableDictionary alloc] init];

//Have a for loop that iterates through your array
for(NSDictionary *currentItem in serverArray)
    RowData *newItem = [[RowData alloc] initWithJSONData:currentItem];

    //If category the date key does not exist, then create a new category for it
    if([myData objectForKey:newItem.rowDataDate] == nil)
        //We want to create an array for each category that will hold all the row datas
        [myDate setObject:[NSMutableArray new] forKey:newItem.rowDataDate];
    
    //Grab the array from a particular category and add the current item to this category
    [[myDate objectForKey:newItem.rowDataDate] addObject:newItem];

现在,当您填充表委托方法时,在 titleForHeader tableview 委托方法中,您只需使用 allKeys 属性从 myData 字典中获取类别标题:日期,然后调用 `objectForIndex:在您的委托方法中为 section 计数器提供方法,广告您使用该字符串通过使用 titleForHeader 表视图委托方法来设置标题视图的标题。

在您的cellForRowAtIndexPath: 委托方法中,您只需使用键在myData 数组中获取正确的类别,然后根据row 计数访问数组中的各个对象。

这就是所有兄弟。祝你好运

免责声明,我没有测试过这段代码,这应该可以马上工作:)

【讨论】:

【参考方案2】:

最好的方法是创建一个自定义对象,我们称之为MyDate。我的日期将有两个属性:日期和数组。

@interface MyDate
    @property NSDate *date;
    @property NSArray *items;
@end

您解析字符串,并为每个信息位检查日期。如果日期不在数组中,则添加它。然后将另一个字符串添加到适当的 MyDate 对象的 items 数组中。

这样,items 中的每个对象都从索引 0 开始,就像每个部分中的行一样。因此,以这种方式管理模型可以轻松处理用户界面。

【讨论】:

【参考方案3】:

您可以使用数组和字典来执行此操作,但它会有点混乱,您可能最好创建可以处理此问题的新对象。

我可能会从看起来有点像这样的东西开始

@interface NMKSection : NSObject

@property (nonatomic, strong) NSDate  *date;
@property (nonatomic, strong) NSArray *rows;

@end

@interface NMKDataSource : NSObject

@property (nonatomic, strong) NSArray *data;
@property (nonatomic, strong) NSArray *sectionSortDescriptors;
@property (nonatomic, strong) NSArray *rowSortDescriptors;

- (NMKSection *)sectionAtIndex:(NSInteger)index;
- (void)processData;

@end

这意味着你的UITableViewDataSource 看起来很简单

- (void)methodToSetupDataSource

  self.dataSource = [[NMKDataSource alloc] init];
  self.dataSource.data                   = data
  self.dataSource.sectionSortDescriptors = // optional;
  self.dataSource.rowSortDescriptors     = // optional;
  [self processData];


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

  NMKSection *section = [self.dataSource sectionAtIndex:section];
  return [self.dataFormatter stringFromData:section.date];


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

  UITableViewCell *cell = // get cell

  id row = [self.dataSource sectionAtIndex:indexPath.section].rows[indexPath.row];

  // configure cell

  return cell;

为了实现这一点,所有繁重的工作都隐藏在NMKDataSource 中。 NMKSection 的实现可以留空,因为它不包含任何逻辑

@implementation NMKSection

@end

所有的辛苦都是从processData开始

@interface NMKDataSource ()

@property (nonatomic, strong) NSArray *sections;

@end

@implementation NMKDataSource

- (id)init;

  self = [super init];
  if (self) 
    _sections = [[NSMutableArray alloc] init];
  
  return self;


- (NMKSection *)sectionAtIndex:(NSInteger)index;

  return self.sections[index];


- (void)processData

  if (self.sectionSortDescriptors) 
    self.sections = [self.unsortedSections sortedArrayUsingDescriptors:self.sectionSortDescriptors];
   else 
    self.sections = [self.unsortedSections copy];
  


- (NSDictionary *)groupedData;

  NSMutableDictionary *groupedData = [[NSMutableDictionary alloc] init];

  [self.data enumerateObjectsUsingBlock:^(NSDictionary *row, NSUInteger idx, BOOL *stop) 
    NSString       *key  = row[@"date"];
    NSMutableArray *rows = groupedData[key];

    if (!rows) 
      groupedData[key] = rows = [[NSMutableArray alloc] init];
    

    [rows addObject:row[@"rowdata"]];
  ];

  return groupedData;


- (NSArray *)unsortedSections;

  NSMutableArray *unsortedSections = [[NSMutableArray alloc] init];

  [self.groupedData enumerateKeysAndObjectsUsingBlock:^(NSDate *date, NSArray *rows, BOOL *stop) 
    [unsortedSections addObject:(
      NMKSection *section = [[NMKSection alloc] init];

      section.date = date;
      section.rows = rows;

      if (self.rowSortDescriptors) 
        section.rows = [rows sortedArrayUsingDescriptors:self.rowSortDescriptors];
      

      section;
    )];
  ];

  return [unsortedSections copy];


@end

这是在浏览器中编写的,因此未经测试。该代码只是一个示例,说明我可能会从哪里开始并进一步开发,直到我满意为止

【讨论】:

这很好,尤其是- (NMKSection *)sectionAtIndex:(NSInteger)index; 方法,因为它可以让事情看起来很干净,尤其是在视图控制器文件中。我喜欢您为自定义数据模型对象创建datasource 类的方式。我将考虑重构我的项目的某些部分以实现这样的自定义数据源。

以上是关于为 UITableView 标头创建数组的主要内容,如果未能解决你的问题,请参考以下文章

如何创建高度由其标签高度确定的 UITableView 标头?

UITableView创建步骤与常用数据源方法

修改 UITableView 标头中的 UISearchBar 宽度

UITableview 的每个单元格中的不同图像

在为 `tableHeaderView` 设置动画时为 `UITableView` 标头设置动画

在 UITableView 标头中将标签约束设置为 0 时自动布局失败