2

この図のように、UITableView を使用して 2 レベルの階層を持つテーブルを作成することを好みます。ユーザーがヘッダーをタップするたびに、コンテンツが折りたたまれたり展開されたりします。3 日間の調査の結果、2 つの技術的な問題があることがわかりました。

1. 別のテーブルを含むカスタム UITableViewCell

2.セクション ヘッダー ビューを使用します。

今、私は2番目を使用することにしました。また、UITableView はセクション ビューを再利用しないため(UITableView には 2 つのプライベート変数: _reusableHeaderViews と _reusableFooterViews: が含まれていますが)、このタスクを実行するためのカスタム メソッドをいくつか作成しました。1 つのバグを除いて、すべて問題ありません。メソッドreloadSections:withRowAnimationUITableViewRowAnimationFadeで使用すると、ヘッダー ビューが空白のビューになります。

これが私のコードです:

#import "MasterViewController.h"

@interface MasterViewController () 
//remember current section
@property (assign, nonatomic) NSInteger curSession;
@property (strong, nonatomic) NSMutableDictionary *reusableHeaderViews;
@end

@implementation MasterViewController

@synthesize reusableHeaderViews = _reusableHeaderViews;
@synthesize tableView = _tableView;
@synthesize curSession = _curSession;
@synthesize detailViewController = _detailViewController;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Master", @"Master");
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.curSession = -1;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

//method for adding header view into reuse-array
-  (void)registerHeaderView:(UITableViewCell *)headerView forReuseIdentifier:(NSString *)reuseIdentifier
{
    NSMutableDictionary *reusableDictionary  = [self reusableHeaderViews];
    if (reusableDictionary == nil)
    {
        reusableDictionary = [[NSMutableDictionary alloc] init];  //creates a storage dictionary if one doesn’t exist
        self.reusableHeaderViews = reusableDictionary;
    }

    NSMutableArray *arrayForIdentifier = [[self reusableHeaderViews] objectForKey:reuseIdentifier];
    if (arrayForIdentifier == nil)
    {
        //creates an array to store views sharing a reuse identifier if one does not exist
        arrayForIdentifier = [[NSMutableArray alloc] init];        
        [reusableDictionary setObject:arrayForIdentifier forKey:reuseIdentifier];
    }

    [arrayForIdentifier addObject:headerView];
}

//get header view in reuse-array
- (UITableViewCell *)reuseableHeaderForIdentifier:(NSString *)reuseIdentifier
{
    NSMutableArray *arrayOfViewsForIdentifier = [[self reusableHeaderViews]  objectForKey:reuseIdentifier];

    if (arrayOfViewsForIdentifier == nil)
    {
        return nil;  //We don’t have any of this kind!
    }

    NSInteger indexOfAvailableHeaderView = [arrayOfViewsForIdentifier indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
                                            {
                                                //If my view doesn’t have a superview, it’s not on-screen.
                                                return ![obj superview];
                                            }];

    if (indexOfAvailableHeaderView != NSNotFound)
    {
        UITableViewCell *headerView = [arrayOfViewsForIdentifier objectAtIndex:indexOfAvailableHeaderView];
        return headerView;    //Success!
    }

    return nil;
}

#pragma mark - Table View

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (_curSession == section)
        return section;
    return 0;
}

- (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *headerReuseIdentifier = @"Header";
    UITableViewCell *cell = [self reuseableHeaderForIdentifier:headerReuseIdentifier];
    if(cell == nil) 
    {
        //Didn’t locate a reusable
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@""];
        [self registerHeaderView:cell forReuseIdentifier:headerReuseIdentifier];
        UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openSection:)];
        tapGR.numberOfTapsRequired = 1;
        [cell addGestureRecognizer:tapGR];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.tag = section;
    cell.textLabel.text = [NSString stringWithFormat:@"Section title %i", section];

    return cell;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    cell.textLabel.text = [NSString stringWithFormat:@"Row %i - section %i", indexPath.row, indexPath.section];
    return cell;
}

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

}

- (void) openSection:(id)sender

{
    NSInteger section = [[(UITapGestureRecognizer*)sender view] tag];
    if(_curSession == -1)
    {
        _curSession = section;
        [_tableView reloadSections:[NSIndexSet indexSetWithIndex:_curSession] withRowAnimation:UITableViewRowAnimationFade];
    }
    else if(_curSession == section)
    {
        _curSession = -1;
        [_tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
    }
    else if(_curSession != section)
    {
        NSInteger temp = _curSession;
        _curSession = -1;
        [_tableView reloadSections:[NSIndexSet indexSetWithIndex:temp] withRowAnimation:UITableViewRowAnimationFade];
        _curSession = section;
        [_tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
    }
}

@end
4

1 に答える 1