展开和折叠所有表格视图单元格

问题描述:

我需要一些 UI 建议.

I need some UI advice.

我有一个视图需要加载如下格式的数据:

I have a view that needs to load data formatted like this:

    {
      "heading": "This is a header",
      "content": "This is some detailed content about the header"
    },
    {
      "heading": "This is another headline.",
      "content": " These are more details about the headline. "
    }

这里是参数: 在加载时,它应该只在表格视图中显示标题.点击标题将展开该单元格并加载有关它的内容或详细信息.这是一个粗略的草图:

Here are the parameters: On load, it should just display the headings in a table view. Tapping a heading will expand that cell and load the the content or details about it. Here is a rough sketch:

  • 标题 1
  • 标题 2
  • 标题 3
  • 标题 4
  • 标题 1
  • 标题 2
    • 标题 2 的内容显示在此处

    还需要一个栏按钮项,可以展开或折叠所有单元格.哪个会这样:

    There also needs to be a bar button item that will either expand or collapse all cells. Which would like this:

    • 标题 1
    • 标题 2
    • 标题 3
    • 标题 4
    • 标题 1
      • 标题 1 的内容显示在此处
      • 标题 2 的内容显示在此处
      • 标题 3 的内容显示在此处
      • 标题 4 的内容显示在此处

      我使用了一些奇怪的父/子逻辑来扩展单个单元格,但我认为我走上了一条黑暗的道路,因为现在我正在尝试实现全部扩展/折叠,但我被卡住了.

      I used some weird parent/child logic to get the individual cells to expand, but I think I went down a dark path because now I am trying to implement the expand/collapse all and I am stuck.

      有谁知道任何开源代码可以进行这种类型的手风琴表格视图和/或关于如何设置视图控制器来执行此操作的任何建议?我已经看到一些库扩展和折叠单个单元格,但是能够完成所有这些变得越来越棘手.

      Does anyone know of any open source code that does this type of accordion table view and/or any suggestion on how to setup a view controller to do this? I have seen a few libraries expand and collapse individual cells, but being able to do all of them is getting tricky.

这就是我的做法,也许稍微简单一点,但绝对相似的方法 :)

this is how I do it, perhaps a slightly simpler, although definitely similar approach :)

#import "ViewController.h"

//dont worry, the header is empty except for import <UIKit/UIKit.h>, this is a subclass on UIViewController

@interface ViewController ()<UITableViewDataSource, UITableViewDelegate>

@property (weak, nonatomic) UITableView *tableView;


@end

@implementation ViewController
{
//ivars
  BOOL sectionIsOpen[4]; //we will use this BOOL array to keep track of the open/closed state for each section.  Obviously I have the number of sections fixed at 4 here, but you could make a more dynamic array with malloc() if neccesary..
}



- (void)viewDidLoad {
  [super viewDidLoad];

  UITableView *tv = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
  tv.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  tv.dataSource = self;
  tv.delegate = self;

  [self.view addSubview:tv];
  self.tableView = tv;

  // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark - UITableViewDataSource
-(NSInteger )numberOfSectionsInTableView:(UITableView *)tableView{
  return 4;
}

-(NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  return ((sectionIsOpen[section]) ? [self numberOfRowsInSection:section] : 0);
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

  //put your switch() here...

  return [NSString stringWithFormat:@"I am section %i", (int)section ];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

  static NSString *cellId = @"cellID";

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

  if (!cell) {
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
  }


 //etc etc decorate your cell...
  cell.textLabel.text = [NSString stringWithFormat:@"cell %i / %i", (int)indexPath.section, (int)indexPath.row ];


  return cell;
}
#pragma mark - UITableViewDelegate
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{

  const CGRect fr = CGRectMake(0, 0, 320.0, 40.0 );

  UIButton *btn = [[UIButton alloc]initWithFrame:fr];
  [btn setTitle:[self tableView:tableView titleForHeaderInSection:section] forState:UIControlStateNormal ];
  [btn setTag:section];
  [btn addTarget:self action:@selector(sectionOpenToggle:) forControlEvents:UIControlEventTouchUpInside];


  // add an image, colour etc if you like

  return btn;
}



#pragma mark - tableViewHelpers

//the number of rows in sectionX when it is open...
-(NSInteger )numberOfRowsInSection:(NSInteger )section{

  return section + 1;
}

//opening/closing a section
-(void )setSection:(NSInteger )section toOpen:(BOOL )open{

  if (open != sectionIsOpen[section]) {

//build an array of indexPath objects
    NSMutableArray *indxPths = [NSMutableArray array];
    for (NSInteger i = 0; i < [self numberOfRowsInSection:section]; i ++) {

      [indxPths addObject: [NSIndexPath indexPathForRow:i inSection:section ]
       ];

    }


    [self.tableView beginUpdates];

    if (open) {
      [self.tableView insertRowsAtIndexPaths:indxPths withRowAnimation:UITableViewRowAnimationFade];
      //nb there is a large ENUM of tableViewRowAnimation types to experiment with..

    }else{
      [self.tableView deleteRowsAtIndexPaths:indxPths withRowAnimation:UITableViewRowAnimationFade];

    }
    sectionIsOpen[section] = open;
    [self.tableView endUpdates];

  }
}

-(void )sectionOpenToggle:(id )sender{
  [self setSection:[sender tag] toOpen: !sectionIsOpen[[sender tag]] ];
}

// open/close all sections.
-(void )setAllSectionsOpen:(BOOL )open{

  for (NSInteger i = 0; i < [self numberOfSectionsInTableView:self.tableView]; i ++) {
    [self setSection:i toOpen:open];
  }
}


//these two for your convenience, hook up to navbar items etc..
-(IBAction)openAllSections:(id)sender{
  [self setAllSectionsOpen:YES];
}
-(IBAction)closeAllSections:(id)sender{
  [self setAllSectionsOpen:NO];
}
@end