简体   繁体   English

UITableView重用节标题视图:使用UITableViewRowAnimationFade时标题视图消失

[英]UITableView reuse section header view: header view disappear when using UITableViewRowAnimationFade

I prefer to use UITableView to create table with 2 level hierarchy like this picture. 我更喜欢使用UITableView创建具有2级层次结构的表,如下图所示。 Everytimes user tap on header, content is collapse or expand. 每次用户点击标题,内容就会折叠或展开。 After 3 days research, I found that there are 2 technical: 经过三天的研究,我发现有两种技术:

1.custom UITableViewCell with another table in itself 1.自定义UITableViewCell本身具有另一个表

2.using section header view. 2.使用节标题视图。

Now I decide to use the second. 现在,我决定使用第二个。 And because UITableView does not re-use section view (although UITableView contain 2 private variable: _reusableHeaderViews & _reusableFooterViews:), I created some custom methods to do this task. 并且由于UITableView不会重复使用剖面视图 (尽管UITableView包含2个私有变量:_reusableHeaderViews和_reusableFooterViews :),所以我创建了一些自定义方法来执行此任务。 Every gone okay, except 1 bug: when I using method reloadSections:withRowAnimation with UITableViewRowAnimationFade , the header view become blank view. 一切正常,除了1个错误:当我使用带有UITableViewRowAnimationFade的 reloadSections:withRowAnimation方法时,标头视图变为空白视图。

Here is my code: 这是我的代码:

#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

It's a little late but maybe someone will have similar question. 已经有点晚了,但也许有人会有类似的问题。

You can try to use this component: https://github.com/serverdensity/ios-SDNestedTable 您可以尝试使用此组件: https : //github.com/serverdensity/ios-SDNestedTable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM