web-dev-qa-db-ja.com

iPhoneで展開可能なtableView

enter image description here

このタイプのexpandable/collapsibleテーブルビューにしたいと考えています。画像のように、カテゴリとサブカテゴリがあります。たとえば、「健康と美しさ」はカテゴリであり、下の図のように、このセルをクリックすると、開いているサブカテゴリよりも大きくなります。では、どうすればこのタイプのテーブルビューを作成できますか?私を提案してください。

20
Rahul Patel

最後に、ここに要件が正確に説明されている2つの非常に役立つヘルプリンクを取得します TableViewセクションの展開/折りたたみ
iOSの折りたたみ可能なテーブルビュー

本当に、このような種類のテーブルビューセクションの拡大/縮小に適した記事

17
Rahul Patel

UITableViewに展開可能なセルに次のコードを使用します

- (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] autorelease];
    }
    cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"name"];
    [cell setIndentationLevel:[[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"level"] intValue]];    
    return cell;
}

行の展開と折りたたみのコード– TableView DidSelectRowメソッド

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    NSDictionary *d=[self.arForTable objectAtIndex:indexPath.row];
    if([d valueForKey:@"Objects"]) {
        NSArray *ar=[d valueForKey:@"Objects"];
        BOOL isAlreadyInserted=NO;
        for(NSDictionary *dInner in ar ){
            NSInteger index=[self.arForTable indexOfObjectIdenticalTo:dInner];
            isAlreadyInserted=(index>0 && index!=NSIntegerMax);
            if(isAlreadyInserted) break; 
        }
        if(isAlreadyInserted) {
            [self miniMizeThisRows:ar];
        } else {        
            NSUInteger count=indexPath.row+1;
            NSMutableArray *arCells=[NSMutableArray array];
            for(NSDictionary *dInner in ar ) {
                [arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
                [self.arForTable insertObject:dInner atIndex:count++];
            }
            [tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationLeft];
        }
    }
}

行を最小化および最大化/展開/折りたたむのに役立つメソッド。

-(void)miniMizeThisRows:(NSArray*)ar{
    for(NSDictionary *dInner in ar ) {
        NSUInteger indexToRemove=[self.arForTable indexOfObjectIdenticalTo:dInner];        
        NSArray *arInner=[dInner valueForKey:@"Objects"];
        if(arInner && [arInner count]>0){
            [self miniMizeThisRows:arInner];
        }
        if([self.arForTable indexOfObjectIdenticalTo:dInner]!=NSNotFound) {
            [self.arForTable removeObjectIdenticalTo:dInner];
            [self.tableView deleteRowsAtIndexPaths:
              [NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexToRemove inSection:0]]
                      withRowAnimation:UITableViewRowAnimationRight];
        }
    }
}

ここからソースコードをダウンロードできます。

10
Nimit Parekh

これが役立つ場合:[Access tableview expandable and collapsibleセクション] https://github.com/OliverLetterer/UIExpandableTableView

8
Maadiah

拡張可能なテーブルビューへのアプローチは少し異なります。これは、この種のテーブルビューの一般的な構築方法に合わせたものです。

ヘッダーセルがあります。 Headerstappableでなければならず、次にcellsヘッダーの下にshowまたはhideがあります。これは、ジェスチャーレコグナイザーをヘッダーに追加することで実現できます。タップすると、そのヘッダーの下のすべてのセル(セクション)を削除し、その逆(セルを追加)します。もちろん、「開いている」ヘッダーと「閉じている」ヘッダーの状態を維持する必要があります。

これはいくつかの理由でいいです:

  1. ヘッダーとセルの役割が分離されているため、コードがすっきりしています。
  2. このメソッドは、テーブルビューの構築方法(ヘッダーとセル)にうまく対応しているため、それほど魔法はありません。コードはセルを削除または追加するだけで、iOSの新しいバージョンと互換性があります。

私はこれを達成するために非常にシンプルなライブラリを作りました。テーブルビューがUITableViewセクションのヘッダーとセルで設定されている限り、必要なことはテーブルビューとヘッダーをサブクラス化することだけです。それを試してみてください :)

リンク: https://github.com/fuzz-productions/FZAccordionTableView

enter image description here

6
kgaidis

このコードを使用してみてください...これが役立つかもしれません...そして、必要に応じて自由にコードを編集してください...

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()

@end

@implementation ViewController
@synthesize myTable;
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //myTable.backgroundColor=[UIColor clearColor];
   // self.view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    muArr= [[NSMutableArray alloc]initWithObjects:@"Vinay",@"Anmol",@"Jagriti", nil];
    ExpArr=[[NSMutableArray alloc]initWithObjects:@"Useeee",@"Thissss",@"Codeee", nil];
    otherExpand=100;
    checker=100;

}

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

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(otherExpand==section)
    return ExpArr.count;

    return  0;

}

-(BOOL)tableView:(UITableView *)table canCollapse:(NSIndexPath *)indexPath
{

    return NO;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *Identifier=@"Cell";
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:Identifier];
    if (cell==nil)
    {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier];

    }
    cell.textLabel.text=[ExpArr objectAtIndex:indexPath.row];
    cell.textLabel.backgroundColor=[UIColor clearColor];
    UIView *viewww=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    viewww.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    cell.backgroundView=viewww;

   // cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    [tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLineEtched];
    [tableView setSeparatorColor:[UIColor purpleColor]];

    return cell;

}

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

    UIView *view1=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
    [view1.layer setCornerRadius:20];
    view1.layer.borderWidth=2;
    view1.layer.borderColor=[UIColor brownColor].CGColor;
    UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, 295, 44)];
    label.backgroundColor=[UIColor clearColor];

    label.text=[muArr objectAtIndex:section];
    UIButton *btn=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    btn.frame=CGRectMake(280, -5, 50, 50);
    btn.backgroundColor=[UIColor clearColor];
    btn.tag=section;

    view1.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"wood.png"]];
    label.textColor=[UIColor blackColor];
    label.font=[UIFont fontWithName:@"American TypeWriter" size:18];
    //btn.backgroundColor=[UIColor blackColor];
    [view1 addSubview:btn];
    [view1 addSubview:label];

    [btn addTarget:self action:@selector(Btntap:) forControlEvents:UIControlEventTouchUpInside];

    return view1;
}


-(void)Btntap : (UIButton *)btn
{
    if(otherExpand!=100)
    {
        if (otherExpand==btn.tag)
        {
            NSMutableArray *tempArr2=[[NSMutableArray alloc]init];
            for(int j=0;j<ExpArr.count;j++)
            {
                NSIndexPath *indexx1=[NSIndexPath indexPathForRow:j inSection:otherExpand];
                [tempArr2 addObject:indexx1];
            }
            checker=0;
            otherExpand=100;
            [myTable deleteRowsAtIndexPaths:tempArr2 withRowAnimation:UITableViewRowAnimationAutomatic];
        }

        else
        {
            NSMutableArray *tempArr2=[[NSMutableArray alloc]init];
            for(int j=0;j<ExpArr.count;j++)
            {
                NSIndexPath *indexx1=[NSIndexPath indexPathForRow:j inSection:otherExpand];
                [tempArr2 addObject:indexx1];
            }
            checker=1;
            otherExpand=100;
            [myTable deleteRowsAtIndexPaths:tempArr2 withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }

    if(checker!=0)
    {
        otherExpand=btn.tag;
        //checker=
        NSMutableArray *tempArr=[[NSMutableArray alloc]init];
        for(int i=0;i<ExpArr.count;i++)
        {
            NSIndexPath *indexx=[NSIndexPath indexPathForRow:i inSection:btn.tag];
            [tempArr addObject:indexx];
        }
        [myTable insertRowsAtIndexPaths:tempArr withRowAnimation:UITableViewRowAnimationAutomatic];

        checker=1;
    }
    checker=100;
}



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

@end
5
Vinay Kumar

WWDC 2011には ITableView Changes、Tips and Tricks-session 125 と呼ばれる素晴らしいビデオがあり、このような方法を示しています。
サンプルコードもチェックしてください TVAnimationsGestures

4
Eyal

Swiftでこのアコーディオンの例をご覧ください。 https://github.com/tadija/AEAccordion

enter image description here

(セクションではなくセルを使用して)アコーディオン効果を作成するためのコードはほとんどありません。おまけとして、他のXIBファイル内でXIBファイルを使用するソリューションもあります(カスタムビューを使用するカスタムセルに役立ちます)。

3
tadija

この例を試してください:

拡張可能なTableViewの最良の例

https://github.com/OliverLetterer/UIExpandableTableView

2
Varun

TLIndexPathTools は、このようなことを自然に行うことができます。実際、展開可能なセクションと展開可能なツリー構造の両方に拡張機能があります。展開可能なセクションには Collapse サンプルプロジェクトを、展開可能なツリーには Outlineサンプルプロジェクト を実行してみてください。

TLIndexPathToolsを使用する利点の1つは、シンプルな低レベルAPIとして、一般的なアプローチを使用してあらゆる種類の動的テーブルビューとコレクションビューの問題を解決できることです。また、Core Dataおよびプレーン配列と互換性があります。

1
Timothy Moose

ExpyTableView を使用できます

これは、指定したセルから展開可能なセクションを作成します。 iOS 8.0まで対応。複数のテーブルビューセルを持つ拡張可能なテーブルビューを生成することにより、柔軟性が得られます。状態のセパレータを操作するだけで、エキスパンドに複数のセルを使用していることが誰にもわかりません。

  • その他の解決策:セルを拡張するために高さを操作します。セルの設計で更新が必要な場合は、すべての自動を再構築する必要がありますコード内のレイアウト制約またはロジック。

  • ExpyTableView:複数のセルを使用し、それらを挿入および削除することで展開可能なテーブルビューを作成します(これは展開と折りたたみを意味する場合があります)。将来の設計要求で。必要なことは、新しいUITableViewCellを追加し、そのコードを記述することだけです。簡単に新しいデザインになります。

あなたがしなければならないすべてはimport ExpyTableView その後:

class ViewController: ExpyTableViewDataSource, ExpyTableViewDelegate {

  @IBOutlet weak var expandableTableView: ExpyTableView!

  // First, set data source and delegate for your table view.
  override func viewDidLoad() {
    super.viewDidLoad() 
    expandableTableView.dataSource = self
    expandableTableView.delegate = self
  }

  // Then return your expandable cell instance from expandingCell data source method.
  func expandableCell(forSection section: Int, inTableView tableView: ExpyTableView) -> UITableViewCell {
    // this cell will be displayed at IndexPath with section: section and row 0
  }
} 

以前のテーブルビューセクションが展開可能なテーブルビューセクションになっていることがわかります。 example project をダウンロードして、より詳細な例を参照することもできます。

0
Okhan Okbay

.hファイル

LoadCustomCell *cell1;
NSMutableArray  *arrayForBool;
NSMutableArray  *questionArray;
NSMutableArray  *answerArray;

.mファイル

 viewDidLoadMethod {
 _faqTblView.estimatedRowHeight = 30;
 _faqTblView.rowHeight = UITableViewAutomaticDimension;
 arrayForBool = [[NSMutableArray alloc]init];

 _questionArray = [[NSMutableArray alloc]init];
 _answerArray = [[NSMutableArray alloc]init];
 for (int i = 0; i < _questionArray.count; i++) {
        [arrayForBool addObject:@"0"];
    }
    self.faqTblView.dataSource = self;
    self.faqTblView .delegate = self;
    [self.faqTblView reloadData];
 }

その後

 #pragma mark - TableView Datasource & Delegate Method.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  return [_questionArray count];
 }
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    UILabel *lblText = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 260, 100)];
    lblText.text = [_questionArray objectAtIndex:section];
    return [lblText getLabelHeight] + 20;(created custom class)
 }
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

UITapGestureRecognizer  *headerTapped   = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sectionHeaderTapped:)];
cell1 = [[[NSBundle mainBundle] loadNibNamed:@"LoadCustomCell" owner:self options:nil] objectAtIndex:0];
[cell1 setFrame:CGRectMake(0, 0, cell1.frame.size.width, cell1.frame.size.height)];
NSString *numStr = [NSString stringWithFormat:@"%ld. ",section + 1];
[cell1.sideMenuUserNameLabel setText:[numStr stringByAppendingString:[_questionArray objectAtIndex:section]]];
[cell1 setBackgroundColor:[UIColor lightGrayColor]];
cell1.tag = section;
[cell1 addGestureRecognizer:headerTapped];

return cell1;
}

- (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 < [_questionArray count]; i++) {
        if (indexPath.section==i) {
            [arrayForBool removeObjectAtIndex:i];
            [arrayForBool insertObject:[NSString stringWithFormat:@"%d", !collapsed] atIndex:i];
        }
    }
    NSLog(@"%@", arrayForBool);
    [self.faqTblView reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationAutomatic];
    for (NSIndexPath *indexPath in self.faqTblView.indexPathsForSelectedRows) {
        [self.faqTblView deselectRowAtIndexPath:indexPath animated:NO];
         }
    cell1.imageView.transform = CGAffineTransformMakeRotation(M_PI);
     }
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *questionCellIdentifier = @"questionCellIdentifier";
QuestionCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:questionCellIdentifier];
if (cell == nil) {
    NSArray * myNib;
    myNib =[[NSBundle mainBundle]loadNibNamed:@"QuestionCustomCell" owner:self options:nil];
    cell = (QuestionCustomCell *)[myNib lastObject];
}

BOOL manyCells  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
if(manyCells){
    cell.questionNameLbl.text = [_answerArray objectAtIndex:indexPath.section];
}
return cell;
}
0
User558

このリンクを確認してください:

http://iostechnotips.blogspot.in/2014/05/expandable-uitableview.html

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

* UITableViewデリゲートメソッドviewForHeaderInSectionを使用して、カスタムUIViewを返します。

*サブビューとしてUIButtonをアクション「expandable:(id)sender」で追加し、セクション番号として送信者IDを確認して、テーブルビューを再読み込みします。

0
Rahul