【问题标题】:How to set up UITableView within a UIViewController created on a .xib file如何在 .xib 文件上创建的 UIViewController 中设置 UITableView
【发布时间】:2012-07-13 06:57:23
【问题描述】:

我有这样的课:

@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 中配置的表格。它完全空白且未格式化。如何访问我的表并以编程方式填充数据?

谢谢!

【问题讨论】:

    标签: uitableview uiviewcontroller


    【解决方案1】:

    这个线程上的几个技巧帮助我创建了这个。我将提供一些更完整的代码文件以帮助其他人:

    步骤 1. 将 UITableView 拖到 Storyboard 或 XIB 中的 View Controller 上。在我的示例中,我使用的是故事板。

    第 2 步:打开您的 ViewController(在我的例子中只是 DefaultViewController)并为 UITableView 添加两个代理:UITableViewDelegateUITableViewDataSource。还为人口和 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 步:转到您的 Storyboard 或 XIB 并选择您的 UITableView 并将 datasourcedelegate 出口拖到您的 DefaultViewController 上以将它们连接起来.您还需要将 UITableView 的 Reference Outlet 连接到您在头文件中创建的 IBOutlet tableView 对象。

    完成后,您应该能够运行它,并且示例数据将就位。

    我希望这与该线程上的其他技巧一起能够帮助其他人在 ViewController 上从头开始设置 UITableView。

    【讨论】:

      【解决方案2】:

      如果您在 IB 中配置了 tableView,您不应该也以编程方式创建一个,您应该创建 @property (nonatomic, retain) IBOutlet UITableView *tableView; 并将其连接到您在 IB 中配置的 tableView。
      尝试在tableView的
      - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section下设置断点
      委托方法,看看这个方法是否被调用。

      来自 Apple UITableView 文档:

      UITableView 对象必须具有充当数据源的对象 以及充当委托的对象;通常这些对象是 应用程序委托,或者更常见的是自定义 UITableViewController 对象。数据源必须采用 UITableViewDataSource 协议和委托必须采用 UITableViewDelegate 协议。数据源提供信息 UITableView 需要建表和管理数据模型 当插入、删除或重新排序表的行时。代表 提供表格使用的单元格并执行其他任务,例如 管理附件视图和选择。

      如您所见,如果您没有为 tableView 设置数据源,tableView 将不知道如何显示以及显示什么,所以什么都不会发生。
      您可以通过调用 tableView.dataSource = self; 或在 IB 中从您的 tableView 拖动到文件所有者(即您的 viewController 必须实现 UITableViewDataSource 协议)来设置一个

      UITableViewDataSource 协议中有两种方法是您的数据源必须实现的:

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

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

      如果您不实施这些方法,您将收到编译器警告。
      如果您实现UITableViewDelegate 协议,您可以更好地控制 tableView 的外观 - 例如行/页眉/页脚高度、选择等等......

      来自 Apple UITableView 文档:

      UITableView 覆盖 UIView 的 layoutSubviews 方法,以便它 仅当您创建 UITableView 的新实例时调用 reloadData 或 当您分配新的数据源时。重新加载表格视图清除 当前状态,包括当前选择。但是,如果你 显式调用 reloadData,它会清除此状态和任何后续 直接或间接调用 layoutSubviews 不会触发重新加载。

      在创建 tableView 或分配新数据源时(或者当您明确调用它时......)时会调用 ReloadData。
      这是 tableView 需要知道要显示什么的时候(多少节?,多少行?,以及要显示哪个单元格?) - 所以这是 numberOfRowsInSextion 方法调用的时候。

      【讨论】:

      • 谢谢!这有帮助!我只是注释掉了创建和显示行。何时调用 numberOfRowsInSextion 方法?当你第一次调用 tableView??因为如果我不添加“tableView.dataSource = self;”和“tableView.delegate = self;”行不显示任何内容。
      • 这是一个很好的答案,帮助很大!谢谢!这必须是我读过的关于 tableview 以及它们需要工作的最佳解释之一!做得好!再次感谢 +1,如果可以的话 +10 :)
      【解决方案3】:

      就像 Eyal 所说,您不应该以编程方式在 Interface Builder 中创建 UITableView。相反,只需在 Interface Builder 中创建一个并将其委托和数据源属性分配给 IB 中的 File's Owner 会容易得多。

      完成此操作后,您无需以编程方式创建一个,也无需为 tableview 使用 @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
      

      这应该只是创建一个简单的 UITableView,其中包含您以编程方式输入的三个数据条目。

      如果您有任何问题或疑问,请发表评论。 :)

      希望这会有所帮助。

      【讨论】:

      • 这段代码中究竟在哪里调用了“numberOfRowsInSection”?因为如果我执行类似的代码并在这个方法中添加一个 NSLog 语句,它永远不会被执行。
      • 在填充表格视图时调用它。您需要确保 .h 文件具有 位,并且界面构建器中的 UITableView 将其数据源和委托设置为文件所有者。否则它根本不会被调用。
      猜你喜欢
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-16
      • 2016-04-23
      相关资源
      最近更新 更多