Question

i am working on a tableview which contains main categories and sub categories. Basically main categories are tableview section headers and when user clicks on a button in tableview section header, i set my tableview to show these subcategories (rows) in the tableview.

Everything works great but what i want to do is when a user clicks on the "show subcategories button" in section header, i want that button to animate and rotate 90 degrees. The button is a UIButtonTypeDetailDisclosure type so i guess u got what i want.

The animation works when i add the animation code to my "viewForHeaderInSection" delegate method, but it doesnt work from the outside. strangely the click actions are also working. Heres the code (Just to make things clear, the user can also just click on a main category to show everything in that category with the gesture recognizer):

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{

MainCategory* cat = [self.tableViewArray objectAtIndex:section];

UIView* view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
UILabel* label = [[UILabel alloc]initWithFrame:CGRectMake(55, 0, 300, 44)];
UIView* imageView = [[UIView alloc]initWithFrame:CGRectMake(2, 2, 40, 40)];
imageView.backgroundColor = [UIColor darkGrayColor];
view.backgroundColor = [UIColor lightTextColor];
label.text = cat.name;
label.backgroundColor = [UIColor clearColor];
[view addSubview:label];
[view addSubview:imageView];
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(selectMainCategory:)];
[view addGestureRecognizer:tapGesture];
view.tag = section;
if([cat.subcategories count]>0){
    UIButton* button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    button.frame = CGRectMake(200, 0, 44, 44);
    button.tag = section;
    [button addTarget:self action:@selector(subCategoryClick:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:button];
}
return view;
}

And for my Button Click Action:

- (IBAction)subCategoryClick:(UIButton*)sender{

    NSLog(@"click!");
    MainCategory* cat = [tableViewArray objectAtIndex:sender.tag];
    NSNumber* section = [NSNumber numberWithInt:sender.tag];
    if(![openSections containsObject:section]){
        [openSections addObject:section];


        NSMutableArray* indexPathsToAdd = [NSMutableArray array];
        for(int i = 0;i<[cat.subcategories count];i++){
            [indexPathsToAdd addObject:[NSIndexPath indexPathForRow:i inSection:sender.tag]];
        }
        [self.tableView beginUpdates];
        [self.tableView insertRowsAtIndexPaths:indexPathsToAdd withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView endUpdates];
        [self rotateButton:sender isOpeningSection:YES];

    }else{
        [openSections removeObject:section];

        NSMutableArray* indexPathsToRemove = [NSMutableArray array];
        for(int i = 0;i<[cat.subcategories count];i++){
            [indexPathsToRemove addObject:[NSIndexPath indexPathForRow:i inSection:sender.tag]];
        }
        [self.tableView beginUpdates];
        [self.tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView endUpdates];

        [self rotateButton:sender isOpeningSection:NO];
    }
    [self.tableView reloadData];
}

And at last, my animation method (just to see if it is animating, not the final method):

- (void)rotateButton:(UIButton*)button isOpeningSection:(BOOL)isOpen{
    CABasicAnimation *halfTurn;
    halfTurn = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    halfTurn.fromValue = [NSNumber numberWithFloat:0];
    halfTurn.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
    halfTurn.duration = 0.5;
    halfTurn.repeatCount = HUGE_VALF;
    [[button layer] addAnimation:halfTurn forKey:@"180"];
}

as i said, when i add the rotatebutton contents to the viewForSection method, the button is rotating but it doesnt rotates when called from the lick event. I guess i am targeting the wrong button layer in this method..

Thanks for helping!

Was it helpful?

Solution

I would guess that the call to reloadData is forcing the table view to create a new view from tableView:viewForHeaderInSection:, which immediately removes the old one from the view hierarchy and adds the unrotated one back.

Possible solutions:

  • If you are already doing animation in insertRowsAtIndexPaths or deleteRowsAtIndexPaths, do you need the call to reloadData at all? It most likely is ruining those animations in addition to your rotation animation.

  • You could create your section headers ahead of time (in viewDidLoad perhaps) and just return the reference in tableView:viewForHeaderInSection:. This would keep any animations intact when you call reloadData.

OTHER TIPS

360*PI/180 = 2PI. Thats 360 degree. Use M_PI/2.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top