UITableViewの2種類のデータをスクロール位置を保持したまま切り替えたい
タイトルそのまま.
やりたいこと:
- UITableViewの2種類のデータをボタンを押すことで切り替えたい
- 切り替えを戻したときにスクロール位置は前の状態のままにしたい
うん,日本語が難しい.
データの切り替え
これは簡単.
reloadData
を呼び出すだけ.
ここでは,2つのデータを用意する.
- 動物データ(_data1)
- ヒト/犬/猫/猿/パンダ/キリン/やぎ
- カラス/すずめ/鳩/インコ/オウム
- たい/こい/めだか/まぐろ
- 国数データ(_data2)
- 漢字/古典/長文読解/文法/敬語
- 四則演算/方程式/幾何/三角関数/作図/証明/微積/行列/整数問題
なんで,こんなデータかというと,特に意味は無い.
それらをNSArrayに格納する.
_data1,_data2ともに,NSArray型の変数.
_data1 = @[@[@"ヒト", @"犬", @"猫", @"猿", @"パンダ", @"キリン", @"やぎ"], @[@"カラス", @"すずめ", @"鳩", @"インコ", @"オウム"], @[@"たい", @"こい", @"めだか", @"まぐろ"]]; _data2 = @[@[@"漢字", @"古典", @"長文読解", @"文法", @"敬語"], @[@"四則演算", @"方程式", @"幾何", @"三角関数", @"作図", @"証明", @"微積", @"行列", @"整数問題"]];
どちらのデータを表示するかを表すint型の変数_tableTypeを用意する.
_tableType=1のときが動物データ,_tabeleType=2のときが国数データとする.
で,適当にStoryBoardを使って,ボタンを2つ設置し,それぞれのアクションを設定する.
ボタン1が押されたら動物データを表示する.
プロパティとして,tableViewというUITableViewの変数があるとすると,
- (IBAction)press1:(id)sender { if (_tableType == 2) { _tableType = 1; [self.tableView reloadData]; } }
って感じ.
これをボタン2が押されたときのも作る.
これで,ボタン1を押したら動物データ,ボタン2を押したら国数データが表示ってできる.
本当は,全体を更新するのではなく,見える部分だけを更新するのが良かったりするのかもしれない.
けど,わからない.
スクロール位置の保持
これも簡単だった.
現在のスクロール位置は,
contentOffset
で取得できる.
だから,切り替え時に,それを覚えておけばいい.
動物データのテーブルのスクロール位置を_point1,国数データのテーブルのスクロール位置を_point2として,さっきのpress1メソッドを書き換える(press2メソッドも):
- (IBAction)press1:(id)sender { if (_tableType == 2) { _tableType = 1; _point2 = [self.tableView contentOffset]; [self.tableView reloadData]; [self.tableView setContentOffset:_point1]; } }
こんな感じ.
_point2 = [self.tableView contentOffset];
で,切り替え前のスクロール位置を保持し,
[self.tableView setContentOffset:_point1];
で,前のスクロール位置をセットする.
これで,スクロール位置を保持したまま,切り替えが可能になる.
まとめ
こんな感じ.
ついでに,タイトルも変更するようにしてみた.
SwitchTableViewController.h
#import <UIKit/UIKit.h> @interface SwitchTableViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> @property (weak, nonatomic) IBOutlet UITableView *tableView; @end
SwitchTableViewController.m
#import "SwitchTableViewController.h" @interface SwitchTableViewController () @end @implementation SwitchTableViewController { int _tableType; NSArray *_data1; NSArray *_data2; CGPoint _point1; CGPoint _point2; } - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; _tableType = 1; _data1 = @[@[@"ヒト", @"犬", @"猫", @"猿", @"パンダ", @"キリン", @"やぎ"], @[@"カラス", @"すずめ", @"鳩", @"インコ", @"オウム"], @[@"たい", @"こい", @"めだか", @"まぐろ"]]; _data2 = @[@[@"漢字", @"古典", @"長文読解", @"文法", @"敬語"], @[@"四則演算", @"方程式", @"幾何", @"三角関数", @"作図", @"証明", @"微積", @"行列", @"整数問題"]]; _point1 = CGPointMake(0, 0); _point2 = CGPointMake(0, 0); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if (_tableType == 1) { return [_data1 count]; } else { return [_data2 count]; } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (_tableType == 1) { return [_data1[section] count]; } else { return [_data2[section] count]; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; } NSString *data; if (_tableType == 1) { data = _data1[indexPath.section][indexPath.row]; } else { data = _data2[indexPath.section][indexPath.row]; } cell.textLabel.text = data; return cell; } - (IBAction)press1:(id)sender { if (_tableType == 2) { _tableType = 1; _point2 = [self.tableView contentOffset]; self.title = @"動物"; [self.tableView reloadData]; [self.tableView setContentOffset:_point1]; } } - (IBAction)press2:(id)sender { if (_tableType == 1) { _tableType = 2; _point1 = [self.tableView contentOffset]; self.title = @"国数"; [self.tableView reloadData]; [self.tableView setContentOffset:_point2]; } } @end
storyboard
で,できたのが,こんな感じ.
切り替えが可能で,スクロール位置も覚えてくれている.
上のbackボタンは無視する感じで.