54

概要:

何が機能するかから始めるために、UITableViewInterfaceBuilderを使用してXcodeで生成されたビューに配置されたを持っています。ビューのファイル所有者は、Xcodeで生成されたのサブクラスに設定されUIViewControllerます。このサブクラスに、との実用的な実装numberOfSectionsInTableView: tableView:numberOfRowsInSection:tableView:cellForRowAtIndexPath:テーブルビューdataSourceを追加delegateし、InterfaceBuilderのファイル所有者を介してこのクラスに接続しています。

上記の構成は問題なく機能します。dataSourceこの問題は、このテーブルビューと実装を別のクラスに移動したい場合に発生します。delegateおそらく、テーブルビュー以外にビューに他のコントロールがあり、テーブルビュー関連のコードをそのクラスに移動したいためです。独自のクラス。これを達成するために、私は次のことを試みます:

  • UITableViewControllerXcodeでの新しいサブクラスを作成します
  • の既知の適切な実装をnumberOfSectionsInTableView:新しいサブクラスにtableView:numberOfRowsInSection:移動しますtableView:cellForRowAtIndexPath:
  • をInterfaceBuilderの既存のXIBUITableViewControllerの最上位に ドラッグし、このために自動的に作成された/を削除してから、のクラスを新しいサブクラスに一致するように設定しますUIViewUITableViewUITableViewControllerUITableViewController
  • UITableView以前に機能していたの既存のdataSource接続を削除し、delegateそれらを新しい接続に接続しますUITableViewController

完了したとき、私は動作していませんUITableView。私は、一見ランダムに発生する可能性のある3つの結果のうちの1つになります。

  • ロードすると、それを認識しないオブジェクトUITableViewに送信していることを示すランタイムエラーが発生しますtableView:cellForRowAtIndexPath:
  • ロードされると、プロジェクトはUITableViewエラーなしでデバッガーに侵入します
  • エラーはありませんが、表示されUITableViewません

デバッグを行い、この問題を再現するためだけに基本的なプロジェクトを作成したところ、通常、上記の3番目のオプションが表示されます(エラーはありませんが、テーブルビューは表示されません)。NSLog呼び出しをいくつか追加したところ、numberOfSectionsInTableView:numberOfRowsInSection:は両方とも呼び出されていますが、そうでcellForRowAtIndexPath:はないことがわかりました。私は本当に単純なものが欠けていると確信しており、私よりも経験豊富な人にとって答えが明白になることを望んでいました。これが簡単な答えではない場合は、コードまたはサンプルプロジェクトで更新していただければ幸いです。御時間ありがとうございます!

再現するための完全な手順:

  • Xcodeで新しいiPhoneOS、ビューベースのアプリケーションを作成し、それを呼び出しますTableTest
  • TableTestViewController.xibInterface Builderで開き、提供されたビューサーフェスにをドラッグしますUITableView
  • UITableView'sdataSourcedelegate-outletsをファイルの所有者に接続します。ファイルの所有者はすでに-classを表しているはずですTableTestViewController。変更を保存します
  • Xcodeに戻り、次のコードをに追加しますTableTestViewController.m:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSLog(@"Returning num sections");
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"Returning num rows");
    return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Trying to return cell");
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.text = @"Hello";
    NSLog(@"Returning cell");
    return cell;
}
  • Build and Goを実行すると、単語HelloUITableView

  • このUITableViewロジックを別のクラスに移動するために、最初にXcodeで新しいファイルを作成し、UITableViewControllerサブクラスを選択してクラスを呼び出します。TableTestTableViewController

  • 上記のコードスニペットをから削除してTableTestViewController.mに配置しTableTestTableViewController.m、これら3つのメソッドのデフォルトの実装を私たちのものに置き換えます。
  • 同じファイル内のInterfaceBuilderに戻り、をメインIBウィンドウにTableTestViewController.xibドラッグして、自動的に付属していた新しいオブジェクトを削除します。UITableViewControllerUITableView
  • この新規のクラスをに設定UITableViewControllerしますTableTestTableViewController
  • 以前に機能していた既存のバインディングからdataSourceとバインディングを削除し、同じ2つのバインディングを作成した新しいバインディングに再接続します。delegateUITableViewTableTestTableViewController
  • 変更を保存し、ビルドして実行します。取得した結果が得られた場合は、UITableView正しく機能しなくなったことに注意してください。

解決策:iPhone開発者フォーラム からのトラブルシューティングと支援を受けて、解決策を文書化しました!プロジェクトのメインサブクラスには、インスタンスUIViewControllerを指すアウトレットが必要です。UITableViewControllerこれを実現するには、プライマリビューのヘッダー(TableTestViewController.h)に以下を追加するだけです。

#import "TableTestTableViewController.h"

IBOutlet TableTestTableViewController *myTableViewController;

次に、Interface Builderで、ファイルの所有者からの新しいアウトレットをTableTestTableViewControllerメインIBウィンドウに接続します。XIBのUI部分を変更する必要はありません。ユーザーコードが直接使用していなくても、このコンセントを設置するだけで、問題は完全に解決されます。助けてくれた人々に感謝し、解決策を見つけるためにiPhone開発者フォーラムのBaldEagleにクレジットを送ります。

4

4 に答える 4

23

私はあなたの手順に従い、プロジェクトを再作成し、同じ問題に遭遇しました。基本的に、あなたはほとんどそこにいます。欠けているものが2つあります(修正すると機能します):

  • tableViewの を画面上のに接続する必要がありTableTestTableViewControllerますUITableView。前に言ったように、プロパティをIBOutletオーバーライドして作成できるわけではないため、次のようにします。tableViewIBOutlet

    @interface TableTestTableViewController : UITableViewController {
        UITableView *tableView;
    }
    
    @property (nonatomic, retain) IBOutlet UITableView *tableView;
    
  • 次に、 への参照を追加し、TableTestTableViewControllerに保持しTableTestViewControllerます。そうTableTestTableViewControllerしないと、(ペン先に何もぶら下がっていない状態でペン先をロードした後に)解放される可能性があり、そのため、不規則な結果、クラッシュ、または何も表示されません。それを行うには、次を追加します。

    @interface TableTestViewController : UIViewController {
        TableTestTableViewController *tableViewController;
    }
    
    @property (nonatomic, retain) IBOutlet TableTestTableViewController  *tableViewController;
    

    それをInterface BuilderでTableTestTableViewControllerインスタンスに接続します。

上記で、これは私のマシンでうまくいきました。

また、これらすべての背後にある動機を述べるのも良いと思います (単に をUITableViewController独自の とともに使用するのではなくUITableView)。私の場合UITableView、同じ画面いっぱいのコンテンツにある他のビューを使用することでした。UILabelsそのため、その他またはUIImages下に追加して、それらUIViewの下または上に表示することができます。UITableView

于 2008-11-01T18:03:18.370 に答える
3

はい、何らかの理由で(理由を知っている人は声をかけてください...)tableViewのプロパティは、公共のプロパティであるにもかかわらず、UITableViewController公開されていません。IBOutletそのため、Interface Builder を使用する場合、そのプロパティを表示して他の に接続することはできませんUITableView。したがって、サブクラスでは、tableViewとしてマークされたプロパティを作成し、IBOutletそれを接続できます。

これはすべてハッキーで回避策のように思えますが、a を分離しUITableViewController's UITableViewて UI 階層の別の場所に配置する唯一の方法のようです。以外のものがあるビューをデザインしようとしたときに同じ問題に遭遇し、UITableViewそれが私が解決した方法でした...これは正しいアプローチですか?

于 2008-10-31T20:16:48.257 に答える
2

私はこれを機能させることができました。4 つの TableView とビデオ付きの Web ビューを備えた非常に優れたダッシュボードを作成しました。重要なのは、個別のtableViewコントローラーと、View Controllerで定義された他のtableviewコントローラーへのIBOutletsを持つことです。UIB では、他のテーブルビュー コントローラーをビュー コントローラーのファイル所有者に接続するだけです。次に、データソースとデリゲートの対応するビュー コントローラーにテーブルを接続します。

于 2012-03-10T23:03:13.487 に答える