web-dev-qa-db-ja.com

.xibファイルに作成されたUIViewController内でUITableViewを設定する方法

私はこのようなクラスを持っています:

@interface ExerciseLogDetails : UIViewController<UIActionSheetDelegate, UITableViewDelegate, UITableViewDataSource> {

uITextViewが後に続くいくつかの要素を表示しようとしています。 UITextView要素はInterface Builderで作成されます。このコードを実行すると:

- (void)viewDidLoad {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds       style:UITableViewStylePlain];
tableView.dataSource = self; 
tableView.delegate = self;
[self.view addSubview:self.tableView];
}

表は示していますが、Interface Builderで構成した表は示していません。完全に空白でフォーマットされていません。テーブルにアクセスして、プログラムでデータを入力するにはどうすればよいですか?

ありがとうございました!

15
MrSueko

IBでtableViewを構成した場合は、プログラムで1つも作成しないでください。@property (nonatomic, retain) IBOutlet UITableView *tableView;を作成し、それをIBで構成したtableViewに接続する必要があります。
tableViewのにブレークポイントを設定してみてください
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
デリゲートメソッドを使用して、このメソッドが呼び出されるかどうかを確認します。

Apple UITableView docsから:

UITableViewオブジェクトには、データソースとして機能するオブジェクトと、デリゲートとして機能するオブジェクトが必要です。通常、これらのオブジェクトはアプリケーションデリゲート、またはより頻繁にはカスタムUITableViewControllerオブジェクトです。データソースはUITableViewDataSourceプロトコルを採用し、デリゲートはUITableViewDelegateプロトコルを採用する必要があります。データソースは、UITableViewがテーブルを作成するために必要な情報を提供し、テーブルの行が挿入、削除、または並べ替えられたときにデータモデルを管理します。デリゲートは、テーブルで使用されるセルを提供し、アクセサリビューや選択の管理などの他のタスクを実行します。

UがdataSourceをtableViewに設定していないかどうかを確認できるので、tableViewはどのように何を表示するかを認識できないため、何も起こりません。
tableView.dataSource = self;を呼び出すか、IBでtableViewからファイルの所有者(UITableViewDataSourceプロトコルを実装する必要のあるviewController)にドラッグすることで、1つを設定できます。

UITableViewDataSourceプロトコルには、dataSource mustが実装する2つのメソッドがあります。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  

そして

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:  (NSIndexPath *)indexPath  

これらのメソッドを実装しないと、コンパイラの警告が表示されます。
UITableViewDelegateプロトコルを実装すると、行/ヘッダー/フッターの高さ、選択など、tableViewの外観をより詳細に制御できます...

Apple UITableView docsから:

UITableViewはUIViewのlayoutSubviewsメソッドをオーバーライドするので、UITableViewの新しいインスタンスを作成するとき、または新しいデータソースを割り当てるときにのみreloadDataを呼び出します。テーブルビューを再ロードすると、現在の選択を含む現在の状態がクリアされます。ただし、reloadDataを明示的に呼び出すと、この状態はクリアされ、その後のlayoutSubviewsへの直接または間接の呼び出しはリロードをトリガーしません。

ReloadDataは、tableViewが作成されたとき、または新しいdataSourceを割り当てたとき(または明示的に呼び出したときなど)に呼び出されます。
これは、tableViewが何を表示するか(セクションの数、行の数、および表示するセルの数)を知る必要があるときです。つまり、numberOfRowsInSextionメソッドが呼び出されたときです。

12
Eyal

このスレッドのヒントのいくつかは、これを作成するのに役立ちました。他にも役立つように、さらに完全なコードファイルをいくつか提供します。

ステップ1. UITableViewをストーリーボードまたはXIBのビューコントローラーにドラッグします。私の例では、ストーリーボードを使用しています。

ステップ2:ViewController(私の場合は、そのDefaultViewController)を開き、UITableViewの2つのデリゲートを追加します:ITableViewDelegateおよびITableViewDataSource。母集団の単純なデータソースとUITableView IBOutletも追加します。

DefaultViewController.h

#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) NSMutableArray *newsArray;

@end

ステップ3:実装ファイル(DefaultViewController.m)を開き、以下を追加します。

#import "DetailViewController.h"

@interface DetailViewController ()
- (void)configureView;
@end

@implementation DetailViewController

@synthesize newsArray;
@synthesize tableView;

#pragma mark - Managing the detail item

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self configureView];
}

- (void)configureView
{
    // Update the user interface for the detail item.
    self.newsArray = [[NSMutableArray alloc] initWithObjects:@"Hello World",@"Goodbye World", nil];
}



- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // typically you need know which item the user has selected.
    // this method allows you to keep track of the selection

}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
           editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{

    return UITableViewCellEditingStyleDelete;
}

// This will tell your UITableView how many rows you wish to have in each section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.newsArray count];
}

// This will tell your UITableView what data to put in which cells in your table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifer = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];

    // Using a cell identifier will allow your app to reuse cells as they come and go from the screen.
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
    }

    // Deciding which data to put into this particular cell.
    // If it the first row, the data input will be "Data1" from the array.
    NSUInteger row = [indexPath row];
    cell.textLabel.text = [self.newsArray objectAtIndex:row];

    return cell;
}

@end

ステップ4:ストーリーボードまたはXIBに移動してUITableViewを選択し、datasourceおよびdelegateアウトレットをDefaultViewControllerにドラッグして接続します。また、UITableViewのReferencing Outletを、ヘッダーファイルで作成したIBOutlet tableViewオブジェクトに接続する必要があります。

これが完了すると、実行できるようになり、サンプルデータが配置されます。

このスレッドの他のヒントと一緒にこれが他の人がViewControllerで最初からUITableViewをセットアップするのに役立つことを願っています。

18
Flea

Eyalが言ったように、UITableViewをプログラムで作成したり、Interface Builderで作成したりしないでください。代わりに、Interface Builderで作成して、デリゲートとデータソースのプロパティをIBのファイルの所有者に割り当てる方がはるかに簡単です。

これを行ったら、プログラムで作成する必要はなく、テーブルビューの@プロパティも必要ありません。代わりに、UIViewControllerのクラスファイルを次のようにすることができます。

// YourViewController.h

#import <UIKit/UIKit.h>

@interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) NSArray *yourData;

@end

NSArrayには、プログラムでテーブルに入力するデータが含まれます。所有しているデータとテーブル内での配置方法に応じて、NSDictionaryのような他のデータクラスを使用することもできます。

// YourViewController.m

#import "YourViewController.h"

@implementation YourViewController
@synthesize yourData;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Here you are creating some data to go in your table by inputting it as an array.
    // I just used some basic strings as an example.
    NSArray *array = [[NSArray alloc] initWithObjects:@"Data1", @"Data2", @"Data3", nil];
    // Copying the array you just created to your data array for use in your table.
    self.yourData = array;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.yourData = nil;
}

#pragma mark Table View Data Source Methods

// This will tell your UITableView how many rows you wish to have in each section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.yourData count];
}

// This will tell your UITableView what data to put in which cells in your table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifer = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];

    // Using a cell identifier will allow your app to reuse cells as they come and go from the screen.
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
    }

    // Deciding which data to put into this particular cell.
    // If it the first row, the data input will be "Data1" from the array.
    NSUInteger row = [indexPath row];
    cell.textLabel.text = [yourData objectAtIndex:row];

    return cell;
    }

@end

これは、プログラムで入力した3つのデータエントリを持つ単純なUITableViewを作成するだけです。

問題や質問がある場合は、コメントを投稿してください。 :)

お役に立てれば。

2
Bootle