307


例えば  
1,[title,description,link,imgUrl]を持ったjsonをURLから取得  
2,下記のようなtableを作ってクリック時にsequeにlinkを渡す  
というような事がしたいです。

* * *

**title**  
| | description,description  
| img | description,description  
| | description,description  

* * *

jsonを取って来てtitleを通常テーブルに入れるところまでは下記の実装でできました。

[code]

    - (void)getJSON:(NSURL*)url
    {
        //NSURL *url = [NSURL URLWithString:@"http://itunes.apple.com/jp/rss/topfreeapplications/limit=10/json"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    
             NSLog(@"json ok");
            NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    
            // データの配列をプロパティに保持
            self.items = [jsonDictionary objectForKey:@"items"]
    
            NSLog(@"%d",(int)[self.items count]);
    
            // TableView をリロード
            [self.tableView reloadData];
        }];
    }
    
    
    // テーブルセルの内容を設定
    - (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];
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
    
        NSDictionary *item = [self.items objectAtIndex:indexPath.row];
        // titleを設定
        cell.textLabel.text = [item objectForKey:@"title"];
        //cellにdescriptionを設定
        //cellにimageを設定
        //cellを押した時に発生するsequeを指定、link要素を渡す
        return cell;
    }
    
[/code]


CC BY-SA 3.0
2014-12-03T02:17:57.680
287
2014-12-03T18:40:36.243
2014-12-03T05:50:38.347
525
525
question
ios json uitableview
iOSでjsonを取得してカスタムのtableViewに流し込みたい


JSONの取得は実装出来ているとのことなので、以下の2.のみ回答させて頂きます。

> 2,下記のようなtableを作ってクリック時にsequeにlinkを渡す というような事がしたいです。

こちら、実現するためには大きくわけて以下の2つの処理が出来れば恐らく意図していることを実装できるかと思います。

1.UITableViewのCellをカスタマイズ

2.Cellがタップされたイベントを検知し、処理を実装

それでは、以下個別に詳細となります。

**1.UITableViewのCellをカスタマイズする方法**

単一のテキスト以外の情報をCell上に表示したい場合、必要となる各要素のViewを作成しcellのsubviewとすることで実現できます。下記は受け取ったdescriptionのテキストを出力するUILabelを作成し、cell上に配置する処理の例です。画像の場合も、同様にUIImageをcellにaddSubviewすることで表示することが出来ます。また、下記ではコードで実装していますがStoryboardを利用して実装している場合は、そちらからこれらの要素を配置することも可能です。

[code]

    // テーブルセルの内容を設定
    - (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];
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
        // description用のLabelを作成し配置する例
        NSDictionary *item = [self.items objectAtIndex:indexPath.row];
        UILabel *descriptionLabel = [[UILabel alloc] init];
        descriptionLabel.textColor = [UIColor blackColor];
        descriptionLabel.font = [UIFont fontWithName:@"AppleGothic" size:12];
        descriptionLabel.text = [item objectForKey:@"description"];
        [descriptionLabel sizeToFit];
        [cell addSubview:descriptionLabel];
        // 上記と同様に必要なViewを作成し、CellにaddSubviewして、座標を調整することで
        // 意図するUIを作れると思います。
    
        // ~ 以下省略 ~
    
[/code]

なお、分かりやすく表現するために上記ではController上に処理を書いていますが今回の用にCellに複数の要素を配置しカスタマイズする場合は、UITableViewCellを継承したサブクラスを作成することが推奨されます。

参考: <http://ios-practice.readthedocs.org/en/latest/docs/tableview/>

また、URLから画像から読み込んで表示する方法については下記に参考となりそうな記事があったのでこちらも共有しておきます。

参考 <http://qiita.com/EntreGulss/items/d7d9fb5d0b93eb509d43>

**2.Cellがタップされたイベントを検知する方法**

UITableViewControllerは、Cellのタップを検知したときにdidSelectRowAtIndexPathメソッドをコールします。そこで、現在実装されているControllerのクラス(UITableViewControllerを継承したものなはず)上でこのメソッドをオーバーライドすることで、Cellがタップされたときのイベント処理を実装することが出来ます。

[code]

    // Cellがタップされた時に以下のメソッドがコールされる
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSDictionary *item = [self.items objectAtIndex:indexPath.row];
        NSString *linkURL = NSS[item objectForKey:@"link"];
        // 画面遷移処理を実装
    }
    
[/code]

上記でセルをカスタマイズしてタップ時に遷移、というのは実装できると思いますがいかがでしょうか。。。


CC BY-SA 3.0
2014-12-03T09:29:59.387
307
2014-12-03T09:29:59.387
766
287
answer


> クリック時にsequeにlinkを渡す

(sequeってsegueですよね）

他の回答で「UITableViewのCellをカスタマイズする方法」と「`didSelectRowAtIndexPath`でCell選択を検知する方法」は出てますので、この回答では
**Segueを使って選択されたCellに関する情報を保持しながら遷移する方法** についてのみ説明します。

今回の例ではTableViewControllerの`Custom
Class`を`SourceTableViewController`、遷移先のViewControllerの`Custom
Class`を`DestinationViewController`だとします。
読む際は実際は、２つのクラス名を実際プロジェクトでご利用のファイル名に脳内変換して御覧ください。

## Step1. StoryBoard上でSegueを定義しておく

StoryBoard上で以下の設定を行います。

  1. 「TableViewController」と「遷移先ViewController」をStoryBoard上に設置
  2. 「TableViewController」の`Custom Class`を`SourceTableViewController`に設定
  3. 「 遷移先Controller」の`Custom Class`を`DestinationViewController`に設定
  4. 「TableViewController」から「遷移先ViewController」へ`Segue`を張り、`Segue`の`identifier`を`toDestinationViewController`に設定

## Step2. DestinationViewController.hにlinkをpropertyとして定義しておく

Cellをタップしたときの遷移先のDestinationViewControllerはlinkを値として受け取る必要があるので
外部から受け取れるようにheaderファイルに`link`をproeprtyとして定義しておきます。

[code]

    # DestinationViewController.h( Cellをタップした時に移動する遷移先のControllerクラス)
    @interface DestinationViewController : UIViewController
    
    # 外部から受け取りたいパラメータを定義(今回は文字列のlink情報)
    @property NSString *link;
    
    @end
    
[/code]

## Step3. SourceTableViewController.mで選択Cellの情報をSegueを経由して遷移先に渡す処理を実装

まずCellが選択された際に遷移が実行されるように`didSelectRowAtIndexPath`の中で`performSegueWithIdentifier`の呼び出しを実装します。

[code]

    # SourceTableViewController.m( JSONを表示するTalebViewControllerのクラス )
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        # "toDestinationViewController"はStoryBoardで設定したSegueのIdentifier
        [self performSegueWithIdentifier:@"toDestinationViewController" sender:nil];
    }
    
[/code]

次にSegueを経由して遷移先のに選択されたCellに表示されている情報をパラメータとして渡す処理を実装します。

`prepareForSegue`が遷移前に呼ばれ、そこでSegueに関する情報を処理できます。

なので、`prepareForSegue`で選択されたCellのlink情報を、遷移先のDestinationViewControllerに渡す処理を実装することで、やりたいことが実現できるはずです。

具体的な実装例は以下のようになります。

[code]

    # SourceTableViewController.m
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        # 選択されたCellのIndexPathを取得します
        NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
    
        # indexPathから、選択されたItemを取得します
        NSDictionary *selectedItem     = self.items[ selectedIndexPath.row ];
    
        # segueが持っている遷移先のViewControllerのインスタンスを取り出します.
        DestinationViewController *destinationViewController =     segue.destinationViewController;
    
        # DestinationViewControllerのインスタンスのプロパティのlinkに選択されたItemのlinkを代入
        destinationViewController.link = [selectedItem objectForKey:@"link"];
    }
    
[/code]

##  Step5. DestinationViewController.mで受け取った値を利用する

今までの実装で、DestinationViewControllerが表示された際にはインスタンスはlink値を持ってるはずです。
viewDidLoad等の中で値が入っていることを確認して利用してください。

[code]

    # DestinationViewController.m
    - (void)viewDidLoad {
        [super viewDidLoad];
        # 選択されたCellのlink値が_linkに入っているはず
        NSLog(@"link:%@",_link);
        # _linkを使った処理を実装
    }
    
[/code]

以上の処理で、Segueを利用してUITableViewControllerで選択されたCellの情報を遷移先のControllerに渡すことができると思います。


CC BY-SA 3.0
2014-12-03T18:13:14.100
321
2014-12-03T18:40:36.243
2014-12-03T18:40:36.243
813
813
287
answer