2014-10-29 5 views
2

Я хочу развернуть/свернуть мои разделы UITableView с анимацией. Я использовал this ответ, и он работает сейчас, если я позвоню self.tableView.reloadData(). Но я хочу, чтобы при нажатии на мой пользовательский заголовок UITableView, ячейки раздела должны скользить вниз/вверх с помощью хорошей анимации. Я пытался использовать self.tableView.beginUpdates() и self.tableView.endUpdates(), но я получаю эту ошибку:iOS - Развернуть/свернуть раздел UITableView с анимацией

Invalid update: invalid number of rows in section 0. The number of rows contained in an 
existing section after the update (8) must be equal to the number of rows contained in that 
section before the update (0), plus or minus the number of rows inserted or deleted from 
that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out 
of that section (0 moved in, 0 moved out). 

Вот некоторый код. Метод, который вызывается при нахождении в секции:

func expand(sender:UITapGestureRecognizer){ 

    let tag = (sender.view?.tag)! 

    self.tableView.beginUpdates() 
    if ausgeklappt[tag] { ausgeklappt[tag] = false } 
    else { ausgeklappt[tag] = true } 

    self.tableView.endUpdates() 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // Return the number of rows in the section. 
    let keyDerSection = sortSpieleDict.keys.array[section] 
    let arrayDerSection = sortSpieleDict[keyDerSection]! 
    if ausgeklappt[section] == false { return 0 } 
    else { return arrayDerSection.count } 
} 

Спасибо.

+0

Эй! проверить эту ссылку: http://stackoverflow.com/questions/1938921/expand-collapse-section-in-uitableview?rq=1 Этот очень старый, но может помочь вам. –

+0

Я использовал этот ответ, чтобы настроить все. Но ответ не использует анимацию. Я также связал ответ с моим вопросом. –

+0

мои извинения, я не видел ссылку в вашем вопросе. Я буду размещать код, который я использую в одном из моих проектов за какое-то время. Он использует анимацию wile expand/collapsing. –

ответ

7

Благодаря iOS_DEV я нашел решение: Только одна строка кода сделала трюк. Я только что заменил beginUpdates() и endUpdates() на метод reloadSections(). Теперь он отлично работает!

func expand(sender:UITapGestureRecognizer){ 

     let tag = (sender.view?.tag)! // The tag value is the section of my custom UITabelView header view. 

     if ausgeklappt[tag] { ausgeklappt[tag] = false } 
     else { ausgeklappt[tag] = true } 

     // The next line did the trick! 
     self.tableView.reloadSections(NSIndexSet(index: tag), withRowAnimation: UITableViewRowAnimation.Automatic) 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     // Return the number of rows in the section. 
     let keyDerSection = sortSpieleDict.keys.array[section] 
     let arrayDerSection = sortSpieleDict[keyDerSection]! 

     if ausgeklappt[section] == false 
     { 
      return 0 
     } 
     else 
     { 
      return arrayDerSection.count 
     } 
    } 
+2

Быстро заметите, что ваш 'if ausgeklappt [tag] ...' для обращения к bool может быть записан как 'ausgeklappt [tag] =! Ausgeklappt [tag];' (при условии, что это BOOL массив.) – Olie

+0

swift3: self.tableView.reloadSections (NSIndexSet (индекс: тег) как IndexSet, с: .automatic) – Tinkerbell

2

Я использовал NSMutableSet для отслеживания щелкнутых заголовков. Я поместил UIButton на каждый заголовок, который откликнулся на следующее событие:

#pragma mark - Header Clicked 
-(void) headerClicked:(UIButton *) sender{ 

    if ([set_OpenIndex containsObject:[NSNumber numberWithUnsignedInteger:sender.tag]]) { 
     [set_OpenIndex removeObject:[NSNumber numberWithUnsignedInteger:sender.tag]]; 
     [tableview_Main reloadSections:[NSIndexSet indexSetWithIndex:sender.tag] withRowAnimation:UITableViewRowAnimationAutomatic]; 
    } 
    else{ 

     if (set_OpenIndex.count > 0) { 
      //--- a header is opened already, close the previous one before opening the other 

      [UIView animateWithDuration:0.5 animations:^{ 
       [set_OpenIndex enumerateObjectsUsingBlock:^(id obj, BOOL *stop){ 
        [set_OpenIndex removeObject:obj]; 
        [tableview_Main reloadSections:[NSIndexSet indexSetWithIndex:[obj integerValue]] withRowAnimation:UITableViewRowAnimationAutomatic]; 

       }]; 
      } completion:^(BOOL finished){ 

       [set_OpenIndex addObject:[NSNumber numberWithUnsignedInteger:sender.tag]]; 
       [tableview_Main reloadSections:[NSIndexSet indexSetWithIndex:sender.tag] withRowAnimation:UITableViewRowAnimationAutomatic]; 

      }]; 
     } 
     else{ 
      [set_OpenIndex addObject:[NSNumber numberWithUnsignedInteger:sender.tag]]; 
      [tableview_Main reloadSections:[NSIndexSet indexSetWithIndex:sender.tag] withRowAnimation:UITableViewRowAnimationAutomatic]; 
     } 
    } 
} 

И просто установить количество строк следующим образом:

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 

    if ([set_OpenIndex containsObject:[NSNumber numberWithInteger:section]]) { 
      return 5; // or what ever is the number of rows 
     } 

     return 0; 
} 

Я написал этот код в Objective-C, как я пока не знают о быстром. Это только для логики. Преобразуйте код в соответствии с вашими потребностями.

Примечание: не забудьте установить метку заголовка UIButton в соответствии с номером раздела.

+0

Найден ответ. Проверьте мой ответ ниже :-) Спасибо –

0
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    [self initialization]; 
} 

#pragma mark - Initialization 

-(void)initialization 
{ 
    arrayForBool=[[NSMutableArray alloc]init]; 
    dic_data =[[NSMutableDictionary alloc]init]; 
    [dic_data setValue:@[@"1",@"2"] forKey:@"Section"]; 
    [dic_data setValue:@[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8"] forKey:@"Section1"]; 
    [dic_data setValue:@[@"1",@"2",@"3",@"4"] forKey:@"Section2"]; 

    for (int i=0; i<dic_data.allKeys.count; i++) { 
     [arrayForBool addObject:[NSNumber numberWithBool:NO]]; 
    } 
} 


#pragma mark - 
#pragma mark TableView DataSource and Delegate Methods 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

    if ([[arrayForBool objectAtIndex:section] boolValue]) { 
     NSString *str =[dic_data.allKeys objectAtIndex:section]; 
     return [[dic_data valueForKey:str]count]; 
    } 
    else 
    return 0; 

} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *[email protected]"hello"; 
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellid]; 
    if (cell==nil) { 
     cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid]; 
    } 
    NSString *str =[dic_data.allKeys objectAtIndex:indexPath.section]; 

    cell.textLabel.text = [[dic_data valueForKey:str]objectAtIndex:indexPath.row]; 
    return cell; 
} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return dic_data.allKeys.count; 
} 

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

    /*************** Close the section, once the data is selected ***********************************/ 
    [arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]]; 

    [_expandableTableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic]; 

} 


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if ([[arrayForBool objectAtIndex:indexPath.section] boolValue]) { 
     return 40; 
    } 
    return 0; 

} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    return 40; 
} 

#pragma mark - Creating View for TableView Section 

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

    UIView *sectionView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 280,40)]; 
    sectionView.tag=section; 
    UILabel *viewLabel=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, _expandableTableView.frame.size.width-10, 40)]; 
    viewLabel.backgroundColor=[UIColor clearColor]; 
    viewLabel.textColor=[UIColor blackColor]; 
    viewLabel.font=[UIFont systemFontOfSize:15]; 
    NSString *str =[dic_data.allKeys objectAtIndex:section]; 

    viewLabel.text=[NSString stringWithFormat:@"List of %@",str]; 
    [sectionView addSubview:viewLabel]; 

    /********** Add UITapGestureRecognizer to SectionView **************/ 
    UITapGestureRecognizer *headerTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sectionHeaderTapped:)]; 
    [sectionView addGestureRecognizer:headerTapped]; 

    return sectionView; 


} 


#pragma mark - Table header gesture tapped 

- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer{ 

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag]; 
    if (indexPath.row == 0) { 
     BOOL collapsed = [[arrayForBool objectAtIndex:indexPath.section] boolValue]; 
     for (int i=0; i<dic_data.allKeys.count; i++) { 
      if (indexPath.section==i) { 
       [arrayForBool replaceObjectAtIndex:i withObject:[NSNumber numberWithBool:!collapsed]]; 
      } 
     } 
     [_expandableTableView reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationTop]; 

    } 

} 

Я написал этот код в Objective-C, как я не так много знаний о стриже еще. Это только для логики. Преобразуйте код в соответствии с вашими потребностями.

Смежные вопросы