• 締切済み

Objective-CのTableViewについて

つまづいてなかなか先に進めません。回答の方をよろしくお願いします。 [ソース] - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { switch ([indexPath section]) { case 1: { switch ([indexPath row]) { case 0: { DropDownCell *cell = (DropDownCell*) [tableView cellForRowAtIndexPath:indexPath]; NSIndexPath *path0 = [NSIndexPath indexPathForRow:[indexPath row]+1 inSection:[indexPath section]]; NSIndexPath *path1 = [NSIndexPath indexPathForRow:[indexPath row]+2 inSection:[indexPath section]]; NSIndexPath *path2 = [NSIndexPath indexPathForRow:[indexPath row]+3 inSection:[indexPath section]]; NSArray *indexPathArray = [NSArray arrayWithObjects:path0, path1, path2, nil]; if ([cell isOpen]) { [cell setClosed]; dropDown1Open = [cell isOpen]; [tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop]; } else { [cell setOpen]; dropDown1Open = [cell isOpen]; [tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop]; } break; } default: { dropDown1 = [[[tableView cellForRowAtIndexPath:indexPath] textLabel] text]; NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:[indexPath section]]; DropDownCell *cell = (DropDownCell*) [tableView cellForRowAtIndexPath:path]; [[cell textLabel] setText:dropDown1]; NSIndexPath *path0 = [NSIndexPath indexPathForRow:[path row]+1 inSection:[indexPath section]]; NSIndexPath *path1 = [NSIndexPath indexPathForRow:[path row]+2 inSection:[indexPath section]]; NSIndexPath *path2 = [NSIndexPath indexPathForRow:[path row]+3 inSection:[indexPath section]]; NSArray *indexPathArray = [NSArray arrayWithObjects:path0, path1, path2, nil]; [cell setClosed]; dropDown1Open = [cell isOpen]; [tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop]; break; } } } } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } このようなプログラムを書いたのですが、 UITableViewのCellがなぜか反転してしまいます。 つまり、画像のような状態になった後、再びCellを押すと閉じ、さらに押すともう一度画像のような状態になるのですが、Object1 → Object3 という状態から Object3 → Object1 と順番が逆になってしまうのです。 全く理由がわかりません。ぜひとも回答の方をお願い致します。 初めての投稿ですので、どのように説明していけばいいのかわかりませんでした。 ですが、どうしても直したい問題ですので、よろしくお願い致します。

みんなの回答

回答No.1

まず、どんな動作になっているか現象の説明からわかりません。 > つまり、画像のような状態になった後、再びCellを押すと閉じ、さらに押すともう一度画像のような状態になるので> すが、Object1 → Object3 という状態から Object3 → Object1 と順番が逆になってしまうのです。 Object1とかObject3とか書いていますが、画像にはSection1とOption1~3が 書かれています。ObjectでなくOptionという表示のことを言っているのですか? また、画像はOption1,Option2,Option3の順に表示されていますが、 これは正しい表示状態であり、これと逆順のOption3,Option2,Option1と 表示されてしまうことがあるので、それをどう修正したらよいか? と聞いているのですか? もしそうだとすると、質問は表示順序を意図通りにするにはどうしたらよいか? ということだと思いますが、テーブル表示で最も重要な (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath メソッドの実装がどうなっているか示されていないので、 そのあたりがおかしいんじゃないの? くらいしか言えません。 また、質問に提示されたコードはセルをタップした時の処理(didSelectRowAtIndexPath) が示されていますが、その中で「DropDownCell」という独自作成クラスが使われていて、 そのクラスがどのようになっているか説明されていないので、提示されたコードの正当性も わかりません。 もしかしてDropDownCellというクラス名を使った有名なライブラリがあるのかな と思い、少し検索してみたところ https://github.com/floriankrueger/iOS-Examples--UITableView-Combo-Box/blob/master/DropDownTest/RootViewController.m で、didSelectRowAtIndexPathの実装が同じようになっているサンプルを見つけましたが、 もしかして、このサンプルを参考に実装したのですか? とりあえずこのサンプルを実行してみたところ、正常に動作するので サンプル自体に問題はないと思います。 前述の通り、ここに示されてない (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath メソッドの実装がおかしいんじゃないかと思うので、 元のサンプルとあなたのコードをよく見比べて見ることをお勧めします。 それで解決しないようなら、サンプルとの違いをしっかり補足で説明してください。

関連するQ&A

  • iphoneアプリ開発での変数の受け渡し

    最近iPhoneアプリ開発を始めた者です。 変数の受け渡しについて質問があり、投稿させていただきました。 以下のコード内で、 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 以下で設定したIDに入ったデータを、 -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)senderの中のIDに受け渡したいのですが、どうやら2つのIDが繋がっていません。 自分自身あまりまだ理解できていないこともあり、ざっくりとした聞き方で申し訳ありません。 初歩的な質問だとは思うのですが、なにとぞご教授お願いします。 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 2; } - (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]; } if (indexPath.row == 0){ cell.textLabel.text = @"東京"; }else{ cell.textLabel.text = @"大阪"; } int ID = indexPath.row; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self performSegueWithIdentifier:@"mySegue" sender:self]; } -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"mySegue"]) { SecondTableViewController *viewCon = segue.destinationViewController; viewCon.myValue = ID; } }

  • iphoneプログラミング UITableの複数表示

    すいません、基本的なことだとは思うのですが、どうしても分からないため質問させてください。 UITableView を2つ並べてそれぞれに別々の値を入れていきたいのですがどうすればできますか?? - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *MyIdentifier = @"MyIdentifer"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease]; } cell.text = [listOfContents objectAtIndex:indexPath.row]; return cell; } この関数だとUITableの個別の識別ができないため2つとも同じ値が入ってしまいます。

  • iphoneアプリ開発についての質問です

    tableviewcellにチェックマークを付けるだけの簡単なコードですが、なぜかチェックマークを付けたセルとは別のセルにまでチェックマークがついてしまっています。 また、激しくスクロールするとさっきまで付いていたチェックマークが外れていたりとさらに酷い状態に・・・。 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType == UITableViewCellAccessoryCheckmark) cell.accessoryType = UITableViewCellAccessoryNone; else cell.accessoryType = UITableViewCellAccessoryCheckmark; [tableView deselectRowAtIndexPath:indexPath animated:YES]; } いろんなサイトで見ても上記のコードが最もよく見るコードでした。 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *CellIdentifier = @"ButtonCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; [self updateCell:cell :CellIdentifier atIndexPath:indexPath]; return cell; } - (void)updateCell:(UITableViewCell *)cell :(NSString *)CellIdentifier atIndexPath:(NSIndexPath *)indexPath { BButton *type = (BButton *)[cell viewWithTag:1]; //Buttonはライブラリを使用 [ReturnButton typeButton:type :self.showArr[indexPath.row]]; } チェックマーク以外はUIButtonなども正常に表示されました。 心当たりがあればお願いします。

  • UITableViewDataSourceエラー

    xcode 7.1 (7B91b)を使用しています。 SwiftでViewControllerにUItableViewを追加した時に、 クラスの定義でdoes not conform to protocol ‘UITableViewDataSource’エラーが発生します。 サイトで調べた結果2つのメソッドを記載することとして、下記を追加しましたが、 一向にエラーが取れません。他なにか要因がありますでしょうか?ご教示のほどよろしくお願いします。 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ } func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ return UITableViewCell() } 全体 class ShopListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{ } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ } func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ return UITableViewCell() }

    • ベストアンサー
    • Swift
  • iphoneアプリ開発についての質問です

    storyboardのprototype cellsでカスタムセルを4つ作成しidentifierも設定した状態で、 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static const id identifiers = { @"MetaCell", @"StatusCell", @"EvoCell", @"FormCell" }; NSString *CellIdentifier = identifiers[indexPath.section]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 以下略 という風にしているのですが UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath: というエラーが出てしまいます。 identifierの文字列は何度見ても一致していました。 if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 上記のコードを追加しても、一応エラーは出ませんが当然セルは反映せず真っ白のままです。 if (cell == nil) { if (indexPath.section == 0) { cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; } else if (indexPath.section == 1) { cell = [tableView dequeueReusableCellWithIdentifier:@"StatusCell"]; } else if (indexPath.section == 2) { cell = [tableView dequeueReusableCellWithIdentifier:@"EvoCell"]; } else if (indexPath.section == 3) { cell = [tableView dequeueReusableCellWithIdentifier:@"FormCell"]; } } 一応このようなやりかたでも試しましたが結果は同じでした。 ちなみにこのテーブルビューへは前のビューからsegueで (void)[[segue destinationViewController] initDetailDic:dic]; で遷移してきています。 何度調べても原因がわからず困っています。心当たりはないでしょうか。

  • iphoneアプリ 画像反転の方法

    もしとくに反転のコード組まなければ、実機上でtableviewのcellをクリックすると、反転して青くなって、画面が遷移されます。 考えているのは、回転ではなく反転です。 今回やりたいのは、tableviewのcell上にグレーの画像を貼っておいて、それをクリックすると黒の画像に反転する方法です。 gray.pngを貼りつけてグレーの画面にはできているのですが、 1、黒の画像(black.png)をどうやって貼るのか 2、cellをクリックしたときにどうやってグレー画像から黒画像に反転するのか の2点を教えて頂けたら幸いです。よろしくお願いします。 下記、コードになります。 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return 2; } - (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]; } if ([indexPath row]==0) { UIImage *image = [UIImage imageNamed:@"gray1.png"]; cell.imageView.image = image; }else if ([indexPath row]==1) { UIImage *image = [UIImage imageNamed:@"gray2.png"]; cell.imageView.image = image; } return cell; }

    • ベストアンサー
    • Mac
  • TableViewでセル名が表示されない

    こんにちは。 iPhoneアプリの勉強している者ですが、TableViewControllerを使いセルごとに名前を表示させようとしているのですが、タイトルのみが表示されて肝心のセル名が表示されません。 appDelegate.mにてUINavigationControllerのインスタンス及びUITableViewControllerのインスタンスを作成してUITableViewControllerのインスタンスをrootViewControllerに設定しTableViewを表示させようとしています。 プログラムの記述のどこが間違っているのか教えて頂けると大変助かります。 以下UITableViewControllerのinterfaceセクションとimplementationセクションを掲載しますので、ご指摘お願いします。 #import <UIKit/UIKit.h> @interface SampleForSimpleTable : UITableViewController { NSArray *itemes; } @end @implementation SampleForSimpleTable - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; self.title = @"SimpleTable"; itemes = [[NSArray alloc] initWithObjects:@"ITME 1", @"ITEM 2", @"ITEM 3", @"ITEM 4", @"ITEM 5", @"ITEM 6", nil]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Potentially incomplete method implementation. // Return the number of sections. return 0; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete method implementation. // Return the number of rows in the section. return [itemes count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"default-cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier ]; if (!cell){ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; } cell.textLabel.text = [itemes objectAtIndex:indexPath.row]; // Configure the cell... return cell; }

  • objective-Cについてご相談があります。

    xcode6でMasterDetailApplicationを試しております。 Master画面のセルをクリックしてDetail画面に遷移した際、 標準でDetail画面の中央に貼られているLabelに、クリックした セル内の文字列が表示される様にしたいのです。 しかし、一度目のクリックでは表示されず、二度目のクリックで初めて 一度目にクリックしたセルの文字列がLabelに表示されてしまいます。 つまり見た目上は、Labelの表示がクリックより一回分遅れるのです。 ※添付画像を参考にして下さい 以下がその部分のコードです。 ----------------------------------------------------------------------- // セグエの設定 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { [self tableView]; // セグエを「showDetail」と名付ける if ([[segue identifier] isEqualToString:@"showDetail"]) { // _cellMojiはid型のインスタンス変数。 [[segue destinationViewController] setDetailItem:_cellMoji]; NSLog(@"1番:%@",_cellMoji); } } // セル内の文字列を取得するメソッド - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // セル内の文字列を取得する UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; // 文字列データをNSString型に変換する _cellMoji = cell.textLabel.text; NSLog(@"2番:%@",_cellMoji); } ---------------------------------------------------------------------- 以上、どなたか解決策をご教示頂けないでしょうか。 何卒宜しくお願い致します。

  • iphoneでTableViewに動的追加できない

    UITableViewでWebから取得した情報を表示したく、非同期にCellを追加する テストアプリを書いていたのですが、わからない点がいくつかあります。 以下は非同期追加のテストコードで、実行するとリストに"foo"が一件だけ表示され 2秒おきにリストに”bar”が追加されます。 @interface AddRowTableViewController : UITableViewController { NSMutableArray *dataSouce; } -(void)onTimer:(NSTimer*)timer; @end @implementation AddRowTableViewController - (void)viewDidLoad { // 初期値は空欄 dataSouce = [[NSMutableArray alloc] init]; // (1) // 初期値としてfooを持つ //dataSouce = [[NSMutableArray alloc] initWithObjects:@"foo", nil]; // (1)' // 2秒ごとにbarを追加するためにインターバルタイマをセット [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(onTimer:) userInfo:nil repeats:YES]; } // 2秒ごとに挿入のために呼ばれる -(void)onTimer:(NSTimer*)timer { // barを追加 [dataSouce addObject:@"bar"]; [self.tableView beginUpdates]; NSIndexPath* path = [NSIndexPath indexPathForRow:0 inSection:0]; // (2) [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationTop]; [self.tableView endUpdates]; // (3) [self.tableView reloadData]; // (4) } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [dataSouce count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *id = @"default-cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:id]; if(!cell){ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:id]; [cell autorelease]; } cell.textLabel.text = [dataSouce objectAtIndex:indexPath.row]; return cell; } #if 0 // (5) - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if([dataSouce count] > 0) return 1; else return 0; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { // テストなので、聞かれたらTitleと答えておく return @"title"; } #endif @end このプログラムは一応動作するのですが、少し変えると期待通りに動作しません。 疑問1 コード中の(1)をコメントアウト及び(1)’をコメントインした状態で、初期値として "foo"が画面に表示された状態からスタートするようになりますが、このとき (2)で先頭に挿入するように記載していますが、実際には2行目に挿入されます。 foo bar bar 例えば4秒後にはこんな感じに並びます。なぜでしょうか? 疑問2 (4)のコードを書くと挿入時にアニメーションしません。(4)のコードを書かないとbarではなく fooが追加されたように見えます。スクロールしてフレームアウト/インなどの動作が あるとセルがリロードされ正しくbarになります。 挿入アニメーションを有効にしつつ最新データを参照させるにはどうしたらよいのでしょうか? 疑問3 (5)を#if 1とすることでセクションが表示されるようになりますが、このときに 初期値として何かあれば追加できますが、初期状態が空欄の場合に追加できず (3)のコードがSIGABRTを発行してしまいます((1)だとNG、(1)’だと通る)。 空欄のセクション付きリストにCellを挿入するにはどうしたらよいでしょうか? 経験が浅く、非常識なコードになっているのではないかと思いますが、 どうにも自力ではこれ以上進めなくなってしまいました。 上記1~3の一つでもいいので、なにかヒントをいただけないでしょうか? 未検証のカンによるアドバイスも歓迎です、こちらで検証させて頂きます。 どうかよろしくお願い致します。

  • UITableViewCellのカスタマイズ

    ObjectiveCを用いてiPhoneアプリ開発の勉強をしています。 ■UITableViewCellに、様々なコントロール要素をのせて表示する方法 http://www.yoheim.net/blog.php?q=20130106 このサイトを参考に、UITableViewCellに、セルごとにボタンやラベルをなどのレイアウトを設定して表示するように取り組んでいるのですが、うまくいきません。 サイトの解説では1つ1つのセルを作る解説がされていて、1つのセルをレイアウトして表示することはできるのですが、 トップ画像のように様々なレイアウトのセルを合わせて表示する方法が解説されておらず、どうすればいいのか分かりませんでした。 TableView部分のコードは以下のように記述しています。 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; } -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // tableCellを取得する。 static NSString *identifier = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; } UISwitch *sw = [[UISwitch alloc] initWithFrame:CGRectZero]; // UISwitchはUIContolを継承しているので、タップされた際の動作を簡単に指定できる。 [sw addTarget:self action:@selector(tapSwich:) forControlEvents:UIControlEventTouchUpInside]; // accessoryViewに代入するときれいに動作します。 cell.accessoryView = sw; cell.textLabel.text = @"Flash Light"; return cell; } この通りに書いてシミュレータを起動すると、サイトトップ画像の一番上のセルと同じレイアウトのセルが2つ表示されます。 (Flash Light とボタンのセルです。) UISwitch *sw の行から cell.textLabel.text = @"Flash Light";の行までをswitch(indexPath.row)文の中に入れると、UISwitch *sw = ... の行でExpected expressionというエラーが出てしまうので 他のレイアウトを表示することができません。 解決策をお願いします。(_ _ )

専門家に質問してみよう