15

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

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

ここで、いくつかの要素の後にUITextViewを表示しようとしています。UITextView要素はInterfaceBuilderで作成されます。このコードを実行する場合:

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

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

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

4

3 に答える 3

18

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

手順1.UITableViewをストーリーボードまたはXIBのいずれかのViewControllerにドラッグします。私の例では、ストーリーボードを使用しています。

ステップ2:ViewController(私の場合はDefaultViewController)を開き、UITableViewの2つのデリゲート( UITableViewDelegateUITableViewDataSource )を追加します。また、母集団とUITableViewIBOutletの単純なデータソースを追加します。

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を選択し、データソースデリゲートアウトレットをDefaultViewControllerにドラッグして接続します。また、UITableViewの参照アウトレットを、ヘッダーファイルで作成したIBOutlettableViewオブジェクトに接続する必要があります。

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

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

于 2013-02-13T19:39:47.730 に答える
12

If you configured a tableView in IB you shouldn't also create one programmatically, you should create @property (nonatomic, retain) IBOutlet UITableView *tableView; and connect it to the tableView you configured in IB.
Try to set a breakpoint in the tableView's
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
delegate method to see if this method get called.

From Apple UITableView docs:

A UITableView object must have an object that acts as a data source and an object that acts as a delegate; typically these objects are either the application delegate or, more frequently, a custom UITableViewController object. The data source must adopt the UITableViewDataSource protocol and the delegate must adopt the UITableViewDelegate protocol. The data source provides information that UITableView needs to construct tables and manages the data model when rows of a table are inserted, deleted, or reordered. The delegate provides the cells used by tables and performs other tasks, such as managing accessory views and selections.

As u can see if u don't set a dataSource to your tableView, the tableView will not know how and what to display, so nothing will happen.
You can set one by calling tableView.dataSource = self; or in IB drag from your tableView to the file's owner (that is your viewController that must implement the UITableViewDataSource Protocol)

There are two methods in the UITableViewDataSource protocol that your dataSource must implement:

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

and

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

If u won't implement those methods u will get a compiler warnings.
You can have more control on how the tableView will look if you implement the UITableViewDelegate protocol - like row/header/footer height, selections and more...

From Apple UITableView docs:

UITableView overrides the layoutSubviews method of UIView so that it calls reloadData only when you create a new instance of UITableView or when you assign a new data source. Reloading the table view clears current state, including the current selection. However, if you explicitly call reloadData, it clears this state and any subsequent direct or indirect call to layoutSubviews does not trigger a reload.

ReloadData get called when the tableView is created or when you assign a new dataSource (or when you explicitly call it of course..).
This is when the tableView needs to know what to display (how many sections?, how many rows?, and which cell to display?) - So this is when numberOfRowsInSextion method called.

于 2012-07-13T09:10:41.290 に答える
2

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

これが完了したら、プログラムで作成する必要はなく、テーブルビューの @property も必要ありません。代わりに、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 が作成されます。

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

お役に立てれば。

于 2012-07-14T19:33:45.770 に答える