ページ 11

tableviewアプリの画面遷移に関して

Posted: 2013年11月13日(水) 16:36
by kosei
現在tableviewを使ったiphoneアプリを作成しています。
データは全てsqliteで引っ張ってきており、litaを使っております。
概要を簡単に示させて頂きます。

Firstviewcontrollerには店舗のリストが書かれており、
店舗を押すと、店舗情報が記載されているdetailviewcontrollerに飛びます。

コード:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
    detailViewController.mission = [mMissions objectAtIndex:indexPath.row];

    [self.navigationController pushViewController:detailViewController animated:YES];

    }
Secondviewcontrollerは検索ページで、渋谷、新宿などのエリアが記載されています。
ここで、渋谷を押した場合は、Firstviewcontrollerに載っている渋谷だけの店舗を表示したいのですが、ここでの画面の遷移のさせ方がわかりません。

secondviewcontrollerのコードは下記です。

コード:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Mission.db"];

    FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
    [db setShouldCacheStatements:YES];
    pArray = [[NSMutableArray alloc] init];
    [db open];
    for (int i=0; i<[aMission count]; i++){
        if(section == i){
            FMResultSet *prs = [db executeQuery:@"select distinct Place from Mission where area = ?", [aMissions objectAtIndex:i]];
            while ([prs next]) {
                Mission *mission = [[Mission alloc] init];
                mission.place = [prs stringForColumn:@"Place"];
                [pArray addObject:mission.place];
            }
            return [pArray count];
        }
    }
    [db close];
    return 0;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    for (int i = 0; i < [aMissions count]; i++){
        if(section == i){
            NSString *str = [[NSString alloc] initWithFormat:@"%@",[aMissions objectAtIndex:i]];
            return str;
        }
    }
    return 0;
}

//tableのセルに表示するデータの指定
- (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];
    }
    pArray = [[NSMutableArray alloc] init];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Mission.db"];
    
    FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
    [db setShouldCacheStatements:YES];
    [db open];
    
    for (int i=0; i<[aMissions count]; i++){
        if(indexPath.section == i){
            FMResultSet *prs = [db executeQuery:@"select distinct Place from Mission where area = ?", [aMissions objectAtIndex:i]];
            while ([prs next]) {
                Mission *mission = [[Mission alloc] init];
                mission.place = [prs stringForColumn:@"Place"];
                [pArray addObject:mission.place];
            }
            cell.textLabel.text = [pArray objectAtIndex:indexPath.row];
        }
    }
    [db close];
    return cell;
    
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ここにて、Firstviewcontrollerに記載されいるリストの中からエリアの一致するものだけを表示するという処理を書けばいいのですが、どのようにかけばいいのかが理解できません。
}


どうか御教授頂けると幸いです。

Re: tableviewアプリの画面遷移に関して

Posted: 2013年11月15日(金) 02:45
by しひ
こんばんは。
Firstviewcontrollerに表示している内容をSQLiteが持っているのなら、
Secondviewcontrollerに表示する内容もSQLiteから引っ張ってくるだけで良いのではないでしょうか。
それより、SecondviewcontrollerではなくThirdviewcontrollerか何かに遷移させて表示したほうが良いのでは?

Re: tableviewアプリの画面遷移に関して

Posted: 2013年11月15日(金) 12:34
by kosei
しひさんご回答ありがとうございます。

私自身も一度はthirdviewcontrollerを作ってそちらに飛ばした方がいいということや、secondviewcontrollerに表示する内容もsqliteから引っ張ってくる来てもいいというように考えました。

しかし、なにも根拠はないのですが、すでに出来上がっているfirstviewcontrollerに飛ばし、条件に合ったものだけを表示する方が、負荷が少なく、効率的に動くのかと思ってしまいました。

実際に、こちらのような点はありえないことなのでしょうか?

現在データの扱い方やプログラミングについては勉強しております。
素人で見当違いのような質問をしていたら申し訳ございません。

教えて頂けると嬉しいです。

Re: tableviewアプリの画面遷移に関して

Posted: 2013年11月16日(土) 04:06
by しひ
狙いはわかりました。ViewControllerの関係はわからなくなってしまいましたが。

とりあえず、ViewControllerとデータを分離しましょう。
店舗リストを持つクラスを用意して、ViewControllerでは生成と表示だけするようにします。
FirstViewControllerで表示したデータを持ち回りたいのであれば、
FirstViewControllerからSecondViewControllerへ店舗リストを渡すようにしたらどうでしょう。

Re: tableviewアプリの画面遷移に関して

Posted: 2013年11月20日(水) 01:28
by kosei
こちらやはり、FirstviewControllerにデータに遷移したいと考えております。
理由としては画面の構造的にそれが今後楽であるからだと考えます。

firstviewcontrollerは、店舗一覧。
firstviewcontroller上で、セルを押すと、detailviewcontrollerに遷移して店舗の詳細が見れる。
secondviewcontrollerは、渋谷、新宿などのエリアが記載されているtableview.
secondviewcontroller上のセルを押す事で、押されたエリアのfirstviewcontrollerに登録されている店舗を表示。この時、さらにその店舗を表示すると、firsrtviewcontrollerで作ったため、detailviewcontrollerに遷移できるようになっています。


そのため、私が上記に書いたコードに加えてこのようにコードを書けばいいのかなと考えたのですが、やはりダメでした。

コード:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 cArray = [[NSMutableArray alloc] init];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Mission.db"];
    
    FMDatabase* db = [FMDatabase databaseWithPath:writableDBPath];
    [db setShouldCacheStatements:YES];
    [db open];
    
    for (int m=0; m<[pArray count]; m++){
        if(indexPath.row == m){
            FMResultSet *trs = [db executeQuery:@"select * from Mission where place = ?", [pArray objectAtIndex:m]];
            while ([trs next]) {
                Mission *mission = [[Mission alloc] init];
                mission.place = [prs stringForColumn:@"Place"];
                [pArray addObject:mission.place];
            }

                FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:[NSBundle mainBundle]];
                [self.navigationController pushViewController:firstViewController animated:YES];                
}
[db close];

Re: tableviewアプリの画面遷移に関して

Posted: 2013年11月22日(金) 03:09
by しひ
わかりました。

まず始めに、-tableView:cellForRowAtIndexPath:メソッド内でデータをつくるのは避けたほうが良いと思います。
これはセルをつくるために呼ばれるメソッドですから、例えばテーブルをスクロールする度にアクセスが発生してしまいます。

2つ目に、セルを選択したときに呼ばれるデリゲートメソッドというのが別にありますので調べてください。
-pushViewController:animated:メソッドはそのメソッド内で呼ぶようにします。

3つ目に、SecondViewControllerで選択したエリアをFirstViewControllerに渡す必要がありますよね。
例えば、

コード:

// FirstViewController
@interface FirstViewController : UIViewController
@property (nonatomic, strong) NSString* area; // 多分文字列?
@end
のようにしておいて

コード:

// SecondViewController
FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:[NSBundle mainBundle]];
firstViewController.area = /* 選択したエリア */;
[self.navigationController pushViewController:firstViewController animated:YES];
とするのはいかがでしょうか。FirstViewControllerでデータをつくるときにself.areaの値を見るようにします。

最後に、リファレンスには必ず目を通すようにしてください。
UITableViewDataSource Protocol Reference
UITableViewDelegate Protocol Reference

Re: tableviewアプリの画面遷移に関して

Posted: 2013年11月22日(金) 13:46
by kosei
アドバイスありがとうございます。
すごく参考になります。
ひとまず試してみます。