29
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

tableViewの中にtableViewを入れ子にする方法

Last updated at Posted at 2015-02-08

tableViewの入れ子構造

縦にスクロールするtableViewの特定の行のセルを、横にスクロールするtableViewのコンテンツにしたかったので、方法を調べました。イメージとしては、以下のようになります。

tableView入れ子.001.jpg

基本的な考え方

基本的には、ViewControllerの中にverticalTableViewがいて、ViewControllerにコントロールを委譲しています。そこでverticalTableViewにverticalTableViewCellを入れます。

verticalTableViewCellには、horizontalTableViewがaddされています。
horizontalTableViewは、 ViewController verticalTableViewCellにコントロールを委譲していて、horizontalTableViewCellを入れています。またhorizontalTableViewのコンテンツおよびスクロール方向を横向きに変更しています。

ViewControllerで2種類のtableViewを制御することになるので、verticalとhorizontalのどちらのtableViewなのかを判別して、処理を分岐させる必要があります。
私の場合はtagで判別しました。
2つのtableViewを一つのViewControllerで制御するのは複雑なので、修正しました。

コード

ViewController.h
# import <UIKit/UIKit.h>
# import "VerticalTableViewCell.h"

@interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) IBOutlet UITableView *verticalTableView;

@end
ViewController.m
# import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // verticalTableViewのdelegate等を設定
    self.verticalTableView.delegate = self;
    self.verticalTableView.dataSource = self;
    
    // セルの再利用登録
    [self.verticalTableView registerClass:[VerticalTableViewCell class]
                   forCellReuseIdentifier:@"vertical"];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // verticalの場合
    // verticalのセルを生成
    VerticalTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"vertical"];
    [cell buildHorizontalTableView];
    
    
    // horizontalTableViewに1以上のタグを設定
    cell.horizontalTableView.tag = indexPath.row +1;
    return cell;

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 10;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 200.0;
}

@end
VerticalTableViewCell.h
# import <UIKit/UIKit.h>

@interface VerticalTableViewCell : UITableViewCell

@property (nonatomic, strong) UITableView *horizontalTableView;
- (void)buildHorizontalTableView;
@end
VerticalTableViewCell.m
# import "VerticalTableViewCell.h"

@implementation VerticalTableViewCell

- (void)buildHorizontalTableView
{
    CGRect frame = CGRectMake(0, 0, 200.0, [UIScreen mainScreen].bounds.size.width);
    self.horizontalTableView = [[UITableView alloc] initWithFrame:frame];
    
    // horizontalセルのdelegate等を設定
    self.horizontalTableView.delegate = self;
    self.horizontalTableView.dataSource = self;
    
    // 横スクロールに変更
    self.horizontalTableView.center = CGPointMake(self.horizontalTableView.frame.origin.x + self.horizontalTableView.frame.size.height / 2, self.horizontalTableView.frame.origin.y + self.horizontalTableView.frame.size.width / 2);
    self.horizontalTableView.transform = CGAffineTransformMakeRotation(-M_PI / 2);
    
    // セルの再利用登録
    [self.horizontalTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"horizontal"];
    
    // tableViewを追加
    [self addSubview:self.horizontalTableView];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // horizontalのセルを生成
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"horizontal"];
    cell.textLabel.text = [NSString stringWithFormat:@"(%ld,%ld)",tableView.tag -1, indexPath.row];
    
    // セルの向きを横向きに
    cell.contentView.transform = CGAffineTransformMakeRotation(M_PI / 2);
    return  cell;
}


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 10;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 100.0;
}

@end

最後に

今まで1つのviewControllerで2つのtableViewを制御することがなかったので、tableViewとViewControllerは1対1だと思い込んでいました。tableViewCellの中のtableViewのコントロールはどこでやればいいのか分からず悩んでいたのですが、なんとか解決できました。delegateの意味をより理解できた気がします。

2015/02/09追記
やはり一つのviewControllerで2つのtableViewを制御するのは、制御が複雑になるので、よろしくないようです。UITableViewDelegateなどのprotocolをUITableViewCellのカスタムクラスに宣言することで、簡単にできるようです。

参考

(iOS/iPhoneアプリ開発) UITableViewを使って横スクロールビューを作成
[UITableViewまわりのきほん]
(http://qiita.com/mag4n/items/bcdf1e88794317cf8c9c)

リポジトリ

29
30
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?